25
25
26
26
from google .ads .googleads .client import GoogleAdsClient
27
27
from google .ads .googleads .errors import GoogleAdsException
28
-
29
-
30
- def main (client , customer_id , ad_group_id ):
28
+ from google .ads .googleads .v21 .common .types import AdTextAsset
29
+ from google .ads .googleads .v21 .resources .types import (
30
+ AdGroupAd ,
31
+ AdGroupCustomizer ,
32
+ CustomizerAttribute ,
33
+ )
34
+ from google .ads .googleads .v21 .services .services .ad_group_ad_service import (
35
+ AdGroupAdServiceClient ,
36
+ )
37
+ from google .ads .googleads .v21 .services .services .ad_group_customizer_service import (
38
+ AdGroupCustomizerServiceClient ,
39
+ )
40
+ from google .ads .googleads .v21 .services .services .customizer_attribute_service import (
41
+ CustomizerAttributeServiceClient ,
42
+ )
43
+ from google .ads .googleads .v21 .services .services .google_ads_service import (
44
+ GoogleAdsServiceClient ,
45
+ )
46
+ from google .ads .googleads .v21 .services .types import (
47
+ AdGroupAdOperation ,
48
+ AdGroupCustomizerOperation ,
49
+ CustomizerAttributeOperation ,
50
+ MutateAdGroupAdsResponse ,
51
+ MutateAdGroupCustomizersResponse ,
52
+ MutateCustomizerAttributesResponse ,
53
+ )
54
+
55
+
56
+ def main (client : GoogleAdsClient , customer_id : str , ad_group_id : str ) -> None :
31
57
"""The main method that creates all necessary entities for the example.
32
58
33
59
Args:
34
60
client: an initialized GoogleAdsClient instance.
35
61
customer_id: a client customer ID.
36
62
ad_group_id: an ad group ID.
37
63
"""
38
- text_customizer_name = f"Planet_{ uuid4 ().hex [:8 ]} "
39
- price_customizer_name = f"Price_{ uuid4 ().hex [:8 ]} "
64
+ text_customizer_name : str = f"Planet_{ uuid4 ().hex [:8 ]} "
65
+ price_customizer_name : str = f"Price_{ uuid4 ().hex [:8 ]} "
40
66
41
- text_customizer_resource_name = create_text_customizer_attribute (
67
+ text_customizer_resource_name : str = create_text_customizer_attribute (
42
68
client , customer_id , text_customizer_name
43
69
)
44
- price_customizer_resource_name = create_price_customizer_attribute (
70
+ price_customizer_resource_name : str = create_price_customizer_attribute (
45
71
client , customer_id , price_customizer_name
46
72
)
47
73
link_customizer_attributes (
@@ -61,7 +87,9 @@ def main(client, customer_id, ad_group_id):
61
87
62
88
63
89
# [START add_ad_customizer]
64
- def create_text_customizer_attribute (client , customer_id , customizer_name ):
90
+ def create_text_customizer_attribute (
91
+ client : GoogleAdsClient , customer_id : str , customizer_name : str
92
+ ) -> str :
65
93
"""Creates a text customizer attribute and returns its resource name.
66
94
67
95
Args:
@@ -72,22 +100,26 @@ def create_text_customizer_attribute(client, customer_id, customizer_name):
72
100
Returns:
73
101
a resource name for a text customizer attribute.
74
102
"""
75
- customizer_attribute_service = client . get_service (
76
- "CustomizerAttributeService"
103
+ customizer_attribute_service : CustomizerAttributeServiceClient = (
104
+ client . get_service ( "CustomizerAttributeService" )
77
105
)
78
106
79
107
# Creates a text customizer attribute. The customizer attribute name is
80
108
# arbitrary and will be used as a placeholder in the ad text fields.
81
- operation = client .get_type ("CustomizerAttributeOperation" )
82
- text_attribute = operation .create
109
+ operation : CustomizerAttributeOperation = client .get_type (
110
+ "CustomizerAttributeOperation"
111
+ )
112
+ text_attribute : CustomizerAttribute = operation .create
83
113
text_attribute .name = customizer_name
84
114
text_attribute .type_ = client .enums .CustomizerAttributeTypeEnum .TEXT
85
115
86
- response = customizer_attribute_service .mutate_customizer_attributes (
87
- customer_id = customer_id , operations = [operation ]
116
+ response : MutateCustomizerAttributesResponse = (
117
+ customizer_attribute_service .mutate_customizer_attributes (
118
+ customer_id = customer_id , operations = [operation ]
119
+ )
88
120
)
89
121
90
- resource_name = response .results [0 ].resource_name
122
+ resource_name : str = response .results [0 ].resource_name
91
123
print (
92
124
f"Added text customizer attribute with resource name '{ resource_name } '"
93
125
)
@@ -96,7 +128,9 @@ def create_text_customizer_attribute(client, customer_id, customizer_name):
96
128
97
129
98
130
# [START add_ad_customizer_1]
99
- def create_price_customizer_attribute (client , customer_id , customizer_name ):
131
+ def create_price_customizer_attribute (
132
+ client : GoogleAdsClient , customer_id : str , customizer_name : str
133
+ ) -> str :
100
134
"""Creates a price customizer attribute and returns its resource name.
101
135
102
136
Args:
@@ -107,22 +141,26 @@ def create_price_customizer_attribute(client, customer_id, customizer_name):
107
141
Returns:
108
142
a resource name for a text customizer attribute.
109
143
"""
110
- customizer_attribute_service = client . get_service (
111
- "CustomizerAttributeService"
144
+ customizer_attribute_service : CustomizerAttributeServiceClient = (
145
+ client . get_service ( "CustomizerAttributeService" )
112
146
)
113
147
114
148
# Creates a price customizer attribute. The customizer attribute name is
115
149
# arbitrary and will be used as a placeholder in the ad text fields.
116
- operation = client .get_type ("CustomizerAttributeOperation" )
117
- price_attribute = operation .create
150
+ operation : CustomizerAttributeOperation = client .get_type (
151
+ "CustomizerAttributeOperation"
152
+ )
153
+ price_attribute : CustomizerAttribute = operation .create
118
154
price_attribute .name = customizer_name
119
155
price_attribute .type_ = client .enums .CustomizerAttributeTypeEnum .PRICE
120
156
121
- response = customizer_attribute_service .mutate_customizer_attributes (
122
- customer_id = customer_id , operations = [operation ]
157
+ response : MutateCustomizerAttributesResponse = (
158
+ customizer_attribute_service .mutate_customizer_attributes (
159
+ customer_id = customer_id , operations = [operation ]
160
+ )
123
161
)
124
162
125
- resource_name = response .results [0 ].resource_name
163
+ resource_name : str = response .results [0 ].resource_name
126
164
print (
127
165
f"Added price customizer attribute with resource name '{ resource_name } '"
128
166
)
@@ -132,12 +170,12 @@ def create_price_customizer_attribute(client, customer_id, customizer_name):
132
170
133
171
# [START add_ad_customizer_2]
134
172
def link_customizer_attributes (
135
- client ,
136
- customer_id ,
137
- ad_group_id ,
138
- text_customizer_resource_name ,
139
- price_customizer_resource_name ,
140
- ):
173
+ client : GoogleAdsClient ,
174
+ customer_id : str ,
175
+ ad_group_id : str ,
176
+ text_customizer_resource_name : str ,
177
+ price_customizer_resource_name : str ,
178
+ ) -> None :
141
179
"""Restricts the ad customizer attributes to work with a specific ad group.
142
180
143
181
This prevents the customizer attributes from being used elsewhere and makes
@@ -150,13 +188,19 @@ def link_customizer_attributes(
150
188
text_customizer_resource_name: the resource name of the text customizer attribute.
151
189
price_customizer_resource_name: the resource name of the price customizer attribute.
152
190
"""
153
- googleads_service = client .get_service ("GoogleAdsService" )
154
- ad_group_customizer_service = client .get_service ("AdGroupCustomizerService" )
191
+ googleads_service : GoogleAdsServiceClient = client .get_service (
192
+ "GoogleAdsService"
193
+ )
194
+ ad_group_customizer_service : AdGroupCustomizerServiceClient = (
195
+ client .get_service ("AdGroupCustomizerService" )
196
+ )
155
197
156
198
# Binds the text attribute customizer to a specific ad group to make sure
157
199
# it will only be used to customize ads inside that ad group.
158
- mars_operation = client .get_type ("AdGroupCustomizerOperation" )
159
- mars_customizer = mars_operation .create
200
+ mars_operation : AdGroupCustomizerOperation = client .get_type (
201
+ "AdGroupCustomizerOperation"
202
+ )
203
+ mars_customizer : AdGroupCustomizer = mars_operation .create
160
204
mars_customizer .customizer_attribute = text_customizer_resource_name
161
205
mars_customizer .value .type_ = client .enums .CustomizerAttributeTypeEnum .TEXT
162
206
mars_customizer .value .string_value = "Mars"
@@ -166,8 +210,10 @@ def link_customizer_attributes(
166
210
167
211
# Binds the price attribute customizer to a specific ad group to make sure
168
212
# it will only be used to customize ads inside that ad group.
169
- price_operation = client .get_type ("AdGroupCustomizerOperation" )
170
- price_customizer = price_operation .create
213
+ price_operation : AdGroupCustomizerOperation = client .get_type (
214
+ "AdGroupCustomizerOperation"
215
+ )
216
+ price_customizer : AdGroupCustomizer = price_operation .create
171
217
price_customizer .customizer_attribute = price_customizer_resource_name
172
218
price_customizer .value .type_ = (
173
219
client .enums .CustomizerAttributeTypeEnum .PRICE
@@ -177,8 +223,11 @@ def link_customizer_attributes(
177
223
customer_id , ad_group_id
178
224
)
179
225
180
- response = ad_group_customizer_service .mutate_ad_group_customizers (
181
- customer_id = customer_id , operations = [mars_operation , price_operation ]
226
+ response : MutateAdGroupCustomizersResponse = (
227
+ ad_group_customizer_service .mutate_ad_group_customizers (
228
+ customer_id = customer_id ,
229
+ operations = [mars_operation , price_operation ],
230
+ )
182
231
)
183
232
184
233
for result in response .results :
@@ -191,12 +240,12 @@ def link_customizer_attributes(
191
240
192
241
# [START add_ad_customizer_3]
193
242
def create_ad_with_customizations (
194
- client ,
195
- customer_id ,
196
- ad_group_id ,
197
- text_customizer_name ,
198
- price_customizer_name ,
199
- ):
243
+ client : GoogleAdsClient ,
244
+ customer_id : str ,
245
+ ad_group_id : str ,
246
+ text_customizer_name : str ,
247
+ price_customizer_name : str ,
248
+ ) -> None :
200
249
"""Creates a responsive search ad (RSA).
201
250
202
251
The RSA uses the ad customizer attributes to populate the placeholders.
@@ -208,41 +257,45 @@ def create_ad_with_customizations(
208
257
text_customizer_name: name of the text customizer.
209
258
price_customizer_name: name of the price customizer.
210
259
"""
211
- googleads_service = client .get_service ("GoogleAdsService" )
212
- ad_group_ad_service = client .get_service ("AdGroupAdService" )
260
+ googleads_service : GoogleAdsServiceClient = client .get_service (
261
+ "GoogleAdsService"
262
+ )
263
+ ad_group_ad_service : AdGroupAdServiceClient = client .get_service (
264
+ "AdGroupAdService"
265
+ )
213
266
214
267
# Creates a responsive search ad using the attribute customizer names as
215
268
# placeholders and default values to be used in case there are no attribute
216
269
# customizer values.
217
- operation = client .get_type ("AdGroupAdOperation" )
218
- ad_group_ad = operation .create
270
+ operation : AdGroupAdOperation = client .get_type ("AdGroupAdOperation" )
271
+ ad_group_ad : AdGroupAd = operation .create
219
272
ad_group_ad .ad .final_urls .append ("https://www.example.com" )
220
273
ad_group_ad .ad_group = googleads_service .ad_group_path (
221
274
customer_id , ad_group_id
222
275
)
223
276
224
- headline_1 = client .get_type ("AdTextAsset" )
277
+ headline_1 : AdTextAsset = client .get_type ("AdTextAsset" )
225
278
headline_1 .text = (
226
279
f"Luxury cruise to {{CUSTOMIZER.{ text_customizer_name } :Venus}}"
227
280
)
228
281
headline_1 .pinned_field = client .enums .ServedAssetFieldTypeEnum .HEADLINE_1
229
282
230
- headline_2 = client .get_type ("AdTextAsset" )
283
+ headline_2 : AdTextAsset = client .get_type ("AdTextAsset" )
231
284
headline_2 .text = f"Only {{CUSTOMIZER.{ price_customizer_name } :10.0€}}"
232
285
233
- headline_3 = client .get_type ("AdTextAsset" )
286
+ headline_3 : AdTextAsset = client .get_type ("AdTextAsset" )
234
287
headline_3 .text = f"Cruise to {{CUSTOMIZER.{ text_customizer_name } :Venus}} for {{CUSTOMIZER.{ price_customizer_name } :10.0€}}"
235
288
236
289
ad_group_ad .ad .responsive_search_ad .headlines .extend (
237
290
[headline_1 , headline_2 , headline_3 ]
238
291
)
239
292
240
- description_1 = client .get_type ("AdTextAsset" )
293
+ description_1 : AdTextAsset = client .get_type ("AdTextAsset" )
241
294
description_1 .text = (
242
295
f"Tickets are only {{CUSTOMIZER.{ price_customizer_name } :10.0€}}!"
243
296
)
244
297
245
- description_2 = client .get_type ("AdTextAsset" )
298
+ description_2 : AdTextAsset = client .get_type ("AdTextAsset" )
246
299
description_2 .text = (
247
300
f"Buy your tickets to {{CUSTOMIZER.{ text_customizer_name } :Venus}} now!"
248
301
)
@@ -251,10 +304,12 @@ def create_ad_with_customizations(
251
304
[description_1 , description_2 ]
252
305
)
253
306
254
- response = ad_group_ad_service .mutate_ad_group_ads (
255
- customer_id = customer_id , operations = [operation ]
307
+ response : MutateAdGroupAdsResponse = (
308
+ ad_group_ad_service .mutate_ad_group_ads (
309
+ customer_id = customer_id , operations = [operation ]
310
+ )
256
311
)
257
- resource_name = response .results [0 ].resource_name
312
+ resource_name : str = response .results [0 ].resource_name
258
313
print (f"Added an ad with resource name '{ resource_name } '" )
259
314
# [END add_ad_customizer_3]
260
315
@@ -282,11 +337,13 @@ def create_ad_with_customizations(
282
337
required = True ,
283
338
help = "An ad group ID." ,
284
339
)
285
- args = parser .parse_args ()
340
+ args : argparse . Namespace = parser .parse_args ()
286
341
287
342
# GoogleAdsClient will read the google-ads.yaml configuration file in the
288
343
# home directory if none is specified.
289
- googleads_client = GoogleAdsClient .load_from_storage (version = "v21" )
344
+ googleads_client : GoogleAdsClient = GoogleAdsClient .load_from_storage (
345
+ version = "v21"
346
+ )
290
347
291
348
try :
292
349
main (googleads_client , args .customer_id , args .ad_group_id )
0 commit comments