Skip to content

Commit 970950b

Browse files
authored
Update add_customer_match_user_list example with option to skip polling (googleads#390)
1 parent a07a249 commit 970950b

1 file changed

Lines changed: 108 additions & 33 deletions

File tree

examples/remarketing/add_customer_match_user_list.py

Lines changed: 108 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,34 +30,20 @@
3030
from 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"\tError with message '{error.message}'.")
57-
if error.location:
58-
for field_path_element in error.location.field_path_elements:
59-
print(f"\t\tOn 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

6349
def _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]
10995
def _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

197190
def _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"\tFailure 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+
252305
def _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"\tError with message '{error.message}'.")
393+
if error.location:
394+
for field_path_element in error.location.field_path_elements:
395+
print(f"\t\tOn field: {field_path_element.field_name}")
396+
sys.exit(1)

0 commit comments

Comments
 (0)