1+ #!/usr/bin/env python
2+ # Copyright 2025 Google LLC
3+ #
4+ # Licensed under the Apache License, Version 2.0 (the "License");
5+ # you may not use this file except in compliance with the License.
6+ # You may obtain a copy of the License at
7+ #
8+ # https://www.apache.org/licenses/LICENSE-2.0
9+ #
10+ # Unless required by applicable law or agreed to in writing, software
11+ # distributed under the License is distributed on an "AS IS" BASIS,
12+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ # See the License for the specific language governing permissions and
14+ # limitations under the License.
15+ """This example is to get impact metrics for a custom budget.
16+
17+ Use this example to get impact metrics for a given budget amount.
18+
19+ This example uses the following:
20+ 1) Performance Max for the campaign type
21+ 2) United States for the geo targeting
22+ 3) Maximize Conversions Value for the bidding strategy
23+
24+ To get budget recommendations, run generate_budget_recommendations.py.
25+ """
26+
27+
28+ import argparse
29+ import sys
30+
31+ from google .ads .googleads .client import GoogleAdsClient
32+ from google .ads .googleads .errors import GoogleAdsException
33+
34+
35+ def main (client , customer_id , user_provided_budget_amount ):
36+ """The main method that creates all necessary entities for the example.
37+
38+ Args:
39+ client: an initialized GoogleAdsClient instance.
40+ customer_id: a client customer ID.
41+ user_provided_budget_amount: a user-provided budget amount (not in micros), to retrieve impact metrics for.
42+ """
43+ recommendation_service = client .get_service ("RecommendationService" )
44+ request = client .get_type ("GenerateRecommendationsRequest" )
45+
46+ request .customer_id = customer_id
47+ request .recommendation_types = ["CAMPAIGN_BUDGET" ]
48+ request .advertising_channel_type = client .enums .AdvertisingChannelTypeEnum .PERFORMANCE_MAX
49+ request .bidding_info .bidding_strategy_type = "MAXIMIZE_CONVERSION_VALUE"
50+ request .positive_locations_ids = [2840 ] # 2840 is for United States
51+ request .asset_group_info = [{ "final_url" : "https://www.your-company.com/" }]
52+ # Multiply the user-provided budget by 1,000,000 to convert to micros, as required for current_budget
53+ request .budget_info .current_budget = round ((user_provided_budget_amount * 1000000 ), 2 )
54+
55+ results = recommendation_service .generate_recommendations (request )
56+
57+ recommendations = results .recommendations
58+
59+ # List to store impact metrics for user input budget
60+ budget_impact_metrics = []
61+
62+ # Get impact metrics for custom budget.
63+ for rec in recommendations :
64+ campaign_budget_rec = rec .campaign_budget_recommendation
65+ # Loop through the budget options in the campaign budget recommendation
66+ # to compile a list of budget amounts and their respective potential
67+ # impact metrics. If you have a campaign creation interface,
68+ # you could display this information for end users to decide which
69+ # budget amount best aligns with their goals.
70+ for budget_option in campaign_budget_rec .budget_options :
71+ if hasattr (budget_option , 'impact' ):
72+ impact = budget_option .impact
73+ budget_amount = budget_option .budget_amount_micros
74+ if budget_amount / 1000000 == user_provided_budget_amount :
75+ budget_data = {
76+ "budget_amount" : round ((budget_amount / 1000000 ), 2 ),
77+ "potential_metrics" : impact .potential_metrics
78+ }
79+ budget_impact_metrics .append (budget_data )
80+ else :
81+ print ("impact metrics not found for this budget amount." )
82+
83+ print (f"budget_impact_metrics:\n { budget_impact_metrics } " )
84+ """
85+ budget_impact_metrics:
86+ [{'budget_amount': 100.0, 'potential_metrics': cost_micros: 700000000
87+ conversions: 12
88+ conversions_value: 481.12592352792007
89+ }]
90+ """
91+
92+
93+ if __name__ == "__main__" :
94+ parser = argparse .ArgumentParser (description = ("Get impact metrics for Performance Max budget." ))
95+ # The following argument(s) should be provided to run the example.
96+ parser .add_argument (
97+ "-c" ,
98+ "--customer_id" ,
99+ type = str ,
100+ required = True ,
101+ help = "The Google Ads customer ID." ,
102+ )
103+ parser .add_argument (
104+ "-b" ,
105+ "--user_provided_budget_amount" ,
106+ type = int ,
107+ required = True ,
108+ help = (
109+ "A budget amount (not in micros) advertiser wants to use."
110+ ),
111+ )
112+
113+ args = parser .parse_args ()
114+
115+ # GoogleAdsClient will read the google-ads.yaml configuration file in the
116+ # home directory if none is specified.
117+ googleads_client = GoogleAdsClient .load_from_storage (version = "v18" )
118+
119+ try :
120+ main (
121+ googleads_client ,
122+ args .customer_id ,
123+ args .user_provided_budget_amount ,
124+ )
125+ except GoogleAdsException as ex :
126+ print (
127+ f'Request with ID "{ ex .request_id } " failed with status '
128+ f'"{ ex .error .code ().name } " and includes the following errors:'
129+ )
130+ for error in ex .failure .errors :
131+ print (f'Error with message "{ error .message } ".' )
132+ if error .location :
133+ for field_path_element in error .location .field_path_elements :
134+ print (f"\t \t On field: { field_path_element .field_name } " )
135+ sys .exit (1 )
0 commit comments