3030from google .ads .google_ads .errors import GoogleAdsException
3131
3232
33- def main (client , customer_id ):
33+ def main (client , customer_id , skip_polling ):
3434 """Uses Customer Match to create and add users to a new user list.
3535
3636 Args:
3737 client: The Google Ads client.
3838 customer_id: The customer ID for which to add the user list.
39+ skip_polling: A bool dictating whether to poll the API for completion.
3940 """
40- try :
41- user_list_resource_name = _create_customer_match_user_list (
42- client , customer_id
43- )
44- _add_users_to_customer_match_user_list (
45- client , customer_id , user_list_resource_name
46- )
47- _print_customer_match_user_list_info (
48- client , customer_id , user_list_resource_name
49- )
50- except GoogleAdsException as ex :
51- print (
52- f"Request with ID '{ ex .request_id } ' failed with status "
53- f"'{ ex .error .code ().name } ' and includes the following errors:"
54- )
55- for error in ex .failure .errors :
56- print (f"\t Error with message '{ error .message } '." )
57- if error .location :
58- for field_path_element in error .location .field_path_elements :
59- print (f"\t \t On field: { field_path_element .field_name } " )
60- sys .exit (1 )
41+ user_list_resource_name = _create_customer_match_user_list (
42+ client , customer_id
43+ )
44+ _add_users_to_customer_match_user_list (
45+ client , customer_id , user_list_resource_name , skip_polling
46+ )
6147
6248
6349def _create_customer_match_user_list (client , customer_id ):
@@ -107,7 +93,7 @@ def _create_customer_match_user_list(client, customer_id):
10793
10894# [START add_customer_match_user_list]
10995def _add_users_to_customer_match_user_list (
110- client , customer_id , user_list_resource_name
96+ client , customer_id , user_list_resource_name , skip_polling
11197):
11298 """Uses Customer Match to create and add users to a new user list.
11399
@@ -116,6 +102,7 @@ def _add_users_to_customer_match_user_list(
116102 customer_id: The customer ID for which to add the user list.
117103 user_list_resource_name: The resource name of the user list to which to
118104 add users.
105+ skip_polling: A bool dictating whether to poll the API for completion.
119106 """
120107 # Creates the OfflineUserDataJobService client.
121108 offline_user_data_job_service_client = client .get_service (
@@ -183,15 +170,21 @@ def _add_users_to_customer_match_user_list(
183170 offline_user_data_job_resource_name
184171 )
185172
186- # Wait until the operation has finished.
187- print ("Request to execute the added operations started." )
188- print ("Waiting until operation completes..." )
189- operation_response .result ()
190-
191- print (
192- "Offline user data job with resource name "
193- f"'{ offline_user_data_job_resource_name } ' has finished."
194- )
173+ if skip_polling :
174+ _check_job_status (
175+ client ,
176+ customer_id ,
177+ offline_user_data_job_resource_name ,
178+ user_list_resource_name ,
179+ )
180+ else :
181+ # Wait until the operation has finished.
182+ print ("Request to execute the added operations started." )
183+ print ("Waiting until operation completes..." )
184+ operation_response .result ()
185+ _print_customer_match_user_list_info (
186+ client , customer_id , user_list_resource_name
187+ )
195188
196189
197190def _build_offline_user_data_job_operations (client ):
@@ -249,6 +242,66 @@ def _build_offline_user_data_job_operations(client):
249242 ]
250243
251244
245+ def _check_job_status (
246+ client ,
247+ customer_id ,
248+ offline_user_data_job_resource_name ,
249+ user_list_resource_name ,
250+ ):
251+ """Retrieves, checks, and prints the status of the offline user data job.
252+
253+ Args:
254+ client: The Google Ads client.
255+ customer_id: The customer ID for which to add the user list.
256+ offline_user_data_job_resource_name: The resource name of the offline
257+ user data job to get the status of.
258+ user_list_resource_name: The resource name of the customer match user
259+ list
260+ """
261+ job_status_enum = client .get_type (
262+ "OfflineUserDataJobStatusEnum" , version = "v6"
263+ ).OfflineUserDataJobStatus
264+ job_type_enum = client .get_type (
265+ "OfflineUserDataJobTypeEnum" , version = "v6"
266+ ).OfflineUserDataJobType
267+ query = f"""
268+ SELECT
269+ offline_user_data_job.resource_name,
270+ offline_user_data_job.id,
271+ offline_user_data_job.status,
272+ offline_user_data_job.type,
273+ offline_user_data_job.failure_reason
274+ FROM offline_user_data_job
275+ WHERE offline_user_data_job.resource_name =
276+ '{ offline_user_data_job_resource_name } '
277+ LIMIT 1"""
278+
279+ # Issues a search request using streaming.
280+ google_ads_service = client .get_service ("GoogleAdsService" , version = "v6" )
281+ results = google_ads_service .search (customer_id , query = query )
282+ offline_user_data_job = next (iter (results )).offline_user_data_job
283+ status = offline_user_data_job .status
284+ status_name = job_status_enum .Name (status )
285+
286+ print (
287+ f"Offline user data job ID '{ offline_user_data_job .id } ' with type "
288+ f"'{ job_type_enum .Name (offline_user_data_job .type )} ' has status: "
289+ f"{ status_name } "
290+ )
291+
292+ if status_name == "SUCCESS" :
293+ _print_customer_match_user_list_info (
294+ client , customer_id , user_list_resource_name
295+ )
296+ elif status_name == "FAILED" :
297+ print (f"\t Failure Reason: { offline_user_data_job .failure_reason } " )
298+ elif status_name in ("PENDING" , "RUNNING" ):
299+ print (
300+ "To check the status of the job periodically, use the following "
301+ f"GAQL query with GoogleAdsService.Search: { query } "
302+ )
303+
304+
252305def _print_customer_match_user_list_info (
253306 client , customer_id , user_list_resource_name
254307):
@@ -316,6 +369,28 @@ def _normalize_and_hash(s):
316369 required = True ,
317370 help = "The Google Ads customer ID." ,
318371 )
372+ parser .add_argument (
373+ "-s" ,
374+ "--skip_polling" ,
375+ action = "store_true" ,
376+ help = "Whether the example should skip polling the API for completion, "
377+ "which can take several hours. If the '-s' flag is set the example "
378+ "will demonstrate how to use a search query to check the status of "
379+ "the uploaded user list." ,
380+ )
381+
319382 args = parser .parse_args ()
320383
321- main (google_ads_client , args .customer_id )
384+ try :
385+ main (google_ads_client , args .customer_id , args .skip_polling )
386+ except GoogleAdsException as ex :
387+ print (
388+ f"Request with ID '{ ex .request_id } ' failed with status "
389+ f"'{ ex .error .code ().name } ' and includes the following errors:"
390+ )
391+ for error in ex .failure .errors :
392+ print (f"\t Error with message '{ error .message } '." )
393+ if error .location :
394+ for field_path_element in error .location .field_path_elements :
395+ print (f"\t \t On field: { field_path_element .field_name } " )
396+ sys .exit (1 )
0 commit comments