Skip to content

Commit 08b28c9

Browse files
authored
Add 10 New Examples (googleads#357)
1 parent 8b660d6 commit 08b28c9

10 files changed

Lines changed: 2542 additions & 60 deletions

File tree

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#!/usr/bin/env python
2+
# Copyright 2020 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+
"""Gets specific details about the most recent changes in the given account.
16+
17+
Changes include the name of the field that changed, and both the old and new
18+
values.
19+
"""
20+
21+
import argparse
22+
from datetime import datetime, timedelta
23+
import sys
24+
25+
from google.ads.google_ads.client import GoogleAdsClient
26+
from google.ads.google_ads.errors import GoogleAdsException
27+
from google.ads.google_ads.util import get_nested_attr
28+
29+
30+
_DEFAULT_PAGE_SIZE = 1000
31+
32+
33+
def main(client, customer_id):
34+
"""Gets specific details about the most recent changes in the given account.
35+
36+
Args:
37+
client: The Google Ads client.
38+
customer_id: The Google Ads customer ID.
39+
"""
40+
google_ads_service = client.get_service("GoogleAdsService", version="v6")
41+
42+
# Construct a query to find details for recent changes in your account.
43+
# The LIMIT clause is required for the change_event resource.
44+
# The maximum size is 10000, but a low limit was set here for demonstrative
45+
# purposes. For more information see:
46+
# https://developers.google.com/google-ads/api/docs/change-event#getting_changes
47+
# The WHERE clause on change_date_time is also required. It must specify a
48+
# window within the past 30 days.
49+
tomorrow = (datetime.now() + timedelta(1)).strftime("%Y-%m-%d")
50+
two_weeks_ago = (datetime.now() + timedelta(-14)).strftime("%Y-%m-%d")
51+
query = f"""
52+
SELECT
53+
change_event.resource_name,
54+
change_event.change_date_time,
55+
change_event.change_resource_name,
56+
change_event.user_email,
57+
change_event.client_type,
58+
change_event.change_resource_type,
59+
change_event.old_resource,
60+
change_event.new_resource,
61+
change_event.resource_change_operation,
62+
change_event.changed_fields
63+
FROM change_event
64+
WHERE change_event.change_date_time <= '{tomorrow}'
65+
AND change_event.change_date_time >= '{two_weeks_ago}'
66+
ORDER BY change_event.change_date_time DESC
67+
LIMIT 5"""
68+
69+
resource_type_enum = client.get_type(
70+
"ChangeEventResourceTypeEnum", version="v6"
71+
).ChangeEventResourceType
72+
operation_type_enum = client.get_type(
73+
"ResourceChangeOperationEnum", version="v6"
74+
).ResourceChangeOperation
75+
76+
try:
77+
results = google_ads_service.search(
78+
customer_id, query=query, page_size=_DEFAULT_PAGE_SIZE
79+
)
80+
81+
for row in results:
82+
event = row.change_event
83+
resource_type = resource_type_enum.Name(event.change_resource_type)
84+
if resource_type == "AD":
85+
old_resource = event.old_resource.ad
86+
new_resource = event.new_resource.ad
87+
elif resource_type == "AD_GROUP":
88+
old_resource = event.old_resource.ad_group
89+
new_resource = event.new_resource.ad_group
90+
elif resource_type == "AD_GROUP_CRITERION":
91+
old_resource = event.old_resource.ad_group_criterion
92+
new_resource = event.new_resource.ad_group_criterion
93+
elif resource_type == "AD_GROUP_BID_MODIFIER":
94+
old_resource = event.old_resource.ad_group_bid_modifier
95+
new_resource = event.new_resource.ad_group_bid_modifier
96+
elif resource_type == "CAMPAIGN":
97+
old_resource = event.old_resource.campaign
98+
new_resource = event.new_resource.campaign
99+
elif resource_type == "CAMPAIGN_BUDGET":
100+
old_resource = event.old_resource.campaign_budget
101+
new_resource = event.new_resource.campaign_budget
102+
elif resource_type == "CAMPAIGN_CRITERION":
103+
old_resource = event.old_resource.campaign_criterion
104+
new_resource = event.new_resource.campaign_criterion
105+
else:
106+
print(
107+
"Unknown change_resource_type: '{event.change_resource_type}'"
108+
)
109+
# If the resource type is unrecognized then we continue to
110+
# the next row.
111+
continue
112+
113+
print(
114+
f"On {event.change_date_time}, user {event.user_email} "
115+
f"used interface {event.client_type} to perform a(n) "
116+
f"{event.resource_change_operation} operation on a "
117+
f"{event.change_resource_type} with resource name "
118+
f"'{event.change_resource_name}'"
119+
)
120+
121+
operation_type = operation_type_enum.Name(
122+
event.resource_change_operation
123+
)
124+
125+
if operation_type in ("UPDATE", "CREATE"):
126+
for changed_field in event.changed_fields.paths:
127+
new_value = get_nested_attr(new_resource, changed_field)
128+
if operation_type == "CREATE":
129+
print(f"\t{changed_field} set to {new_value}")
130+
else:
131+
old_value = get_nested_attr(old_resource, changed_field)
132+
print(
133+
f"\t{changed_field} changed from {old_value} to {new_value}"
134+
)
135+
136+
except GoogleAdsException as ex:
137+
print(
138+
f"Request with ID '{ex.request_id}' failed with status "
139+
f"'{ex.error.code().name}' and includes the following errors:"
140+
)
141+
for error in ex.failure.errors:
142+
print(f"\tError with message '{error.message}'.")
143+
if error.location:
144+
for field_path_element in error.location.field_path_elements:
145+
print(f"\t\tOn field: {field_path_element.field_name}")
146+
sys.exit(1)
147+
148+
149+
if __name__ == "__main__":
150+
# GoogleAdsClient will read the google-ads.yaml configuration file in the
151+
# home directory if none is specified.
152+
google_ads_client = GoogleAdsClient.load_from_storage()
153+
154+
parser = argparse.ArgumentParser(
155+
description="This example gets specific details about the most recent "
156+
"changes in the given account."
157+
)
158+
# The following argument(s) should be provided to run the example.
159+
parser.add_argument(
160+
"-c",
161+
"--customer_id",
162+
type=str,
163+
required=True,
164+
help="The Google Ads customer ID.",
165+
)
166+
args = parser.parse_args()
167+
main(google_ads_client, args.customer_id)

examples/account_management/get_account_changes.py renamed to examples/account_management/get_change_summary.py

Lines changed: 38 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,51 +14,25 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
"""This example gets the changes in the account made in the last 7 days."""
17+
"""This example gets a list of which resources have been changed in an account.
18+
"""
1819

1920

2021
import argparse
2122
import sys
2223

24+
from google.ads.google_ads.client import GoogleAdsClient
25+
from google.ads.google_ads.errors import GoogleAdsException
2326

24-
import google.ads.google_ads.client
25-
26-
27-
ADS_PAGE_SIZE = 1000
27+
_DEFAULT_PAGE_SIZE = 1000
2828

2929

3030
# [START get_account_changes]
31-
def resource_name_for_resource_type(resource_type, row):
32-
"""Return the resource name for the resource type.
33-
34-
Each returned row contains all possible changed fields. This function
35-
returns the resource name of the changed field based on the
36-
resource type. The changed field's parent is also populated but is not used.
37-
38-
Args:
39-
resource_type: the string equivalent of the resource type
40-
row: a single row returned from the service
41-
42-
Returns:
43-
The resource name of the field that changed.
44-
"""
45-
resource_name = "" # default for UNSPECIFIED or UNKNOWN
46-
if resource_type == "AD_GROUP":
47-
resource_name = row.change_status.ad_group
48-
elif resource_type == "AD_GROUP_AD":
49-
resource_name = row.change_status.ad_group_ad
50-
elif resource_type == "AD_GROUP_CRITERION":
51-
resource_name = row.change_status.ad_group_criterion
52-
elif resource_type == "CAMPAIGN":
53-
resource_name = row.change_status.campaign
54-
elif resource_type == "CAMPAIGN_CRITERION":
55-
resource_name = row.change_status.campaign_criterion
56-
return resource_name
57-
# [END get_account_changes]
58-
59-
6031
def main(client, customer_id):
6132
ads_service = client.get_service("GoogleAdsService", version="v6")
33+
34+
# Construct a query to find information about changed resources in your
35+
# account.
6236
query = """
6337
SELECT
6438
change_status.resource_name,
@@ -71,40 +45,46 @@ def main(client, customer_id):
7145
change_status.ad_group_criterion,
7246
change_status.campaign_criterion
7347
FROM change_status
74-
WHERE change_status.last_change_date_time DURING LAST_7_DAYS
75-
ORDER BY change_status.last_change_date_time"""
76-
77-
response = ads_service.search(
78-
customer_id, query=query, page_size=ADS_PAGE_SIZE
79-
)
48+
WHERE change_status.last_change_date_time DURING LAST_14_DAYS
49+
ORDER BY change_status.last_change_date_time
50+
LIMIT 10000"""
8051

8152
resource_type_enum = client.get_type(
8253
"ChangeStatusResourceTypeEnum", version="v6"
8354
).ChangeStatusResourceType
84-
change_status_operation_enum = client.get_type(
55+
change_status_op_enum = client.get_type(
8556
"ChangeStatusOperationEnum", version="v6"
8657
).ChangeStatusOperation
8758

8859
try:
60+
response = ads_service.search(
61+
customer_id, query=query, page_size=_DEFAULT_PAGE_SIZE
62+
)
8963
for row in response:
90-
resource_type = resource_type_enum.Name(
91-
row.change_status.resource_type
92-
)
93-
resource_status = change_status_operation_enum.Name(
94-
row.change_status.resource_status
95-
)
64+
cs = row.change_status
65+
resource_type = resource_type_enum.Name(cs.resource_type)
66+
if resource_type == "AD_GROUP":
67+
resource_name = cs.ad_group
68+
if resource_type == "AD_GROUP_AD":
69+
resource_name = cs.ad_group_ad
70+
if resource_type == "AD_GROUP_CRITERION":
71+
resource_name = cs.ad_group_criterion
72+
if resource_type == "CAMPAIGN":
73+
resource_name = cs.campaign
74+
if resource_type == "CAMPAIGN_CRITERION":
75+
resource_name = cs.campaign_criterion
76+
else:
77+
resource_name = "UNKNOWN"
78+
79+
resource_status = change_status_op_enum.Name(cs.resource_status)
9680
print(
97-
'On "%s", change status "%s" shows a resource type of "%s" '
98-
'with resource name "%s" was "%s".'
99-
% (
100-
row.change_status.last_change_date_time,
101-
row.change_status.resource_name,
102-
resource_type,
103-
resource_name_for_resource_type(resource_type, row),
104-
resource_status,
105-
)
81+
f"On '{cs.last_change_date_time}', change status "
82+
f"'{cs.resource_name}' shows that a resource type of "
83+
f"'{resource_type}' with resource name '{resource_name}' was "
84+
f"{resource_status}"
10685
)
107-
except google.ads.google_ads.errors.GoogleAdsException as ex:
86+
# [END get_account_changes]
87+
except GoogleAdsException as ex:
10888
print(
10989
'Request with ID "%s" failed with status "%s" and includes the '
11090
"following errors:" % (ex.request_id, ex.error.code().name)
@@ -120,9 +100,7 @@ def main(client, customer_id):
120100
if __name__ == "__main__":
121101
# GoogleAdsClient will read a google-ads.yaml configuration file in the
122102
# home directory if none is specified.
123-
google_ads_client = (
124-
google.ads.google_ads.client.GoogleAdsClient.load_from_storage()
125-
)
103+
google_ads_client = GoogleAdsClient.load_from_storage()
126104

127105
parser = argparse.ArgumentParser(
128106
description=(

0 commit comments

Comments
 (0)