Skip to content

Commit 3744ea3

Browse files
committed
AdWords v201609 Release
1 parent 54ecab3 commit 3744ea3

110 files changed

Lines changed: 9914 additions & 50 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
4.6.1 -- 9/30/16:
2+
* Added support for AdWords v201609.
3+
* The library now automatically applies filters to log output to sanitize its
4+
contents of sensitive data. For more details on how to configure logging or
5+
disable log filtering, see the README.
6+
* The library will now log warnings if it detects that it is being run with
7+
Python versions below 2.7.9.
8+
19
4.5.1 -- 8/30/2016:
210
* Resolved issue #148:
311
https://github.com/googleads/googleads-python-lib/issues/148

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,28 @@ for API change announcements and other news.
104104
The library uses Python's built in logging framework. If you wish to log your
105105
SOAP interactions to stdout, you can do the following:
106106
```python
107-
logging.basicConfig(level=logging.INFO)
107+
logging.basicConfig(level=logging.INFO, format=googleads.util.LOGGER_FORMAT)
108108
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
109109
```
110110
If you wish to log to a file, you'll need to attach a log handler to this source
111111
which is configured to write the output to a file.
112112

113113

114+
##How do I disable log filters?
115+
By default, this library will apply log filters to the `googleads.common`,
116+
`suds.client`, and `suds.transport` loggers in order to omit sensitive data. If
117+
you need to see this data in your logs, you can disable the filters with the
118+
following:
119+
```python
120+
logging.getLogger('googleads.common').removeFilter(
121+
googleads.util.GetGoogleAdsCommonFilter())
122+
logging.getLogger('suds.client').removeFilter(
123+
googleads.util.GetSudsClientFilter())
124+
logging.getLogger('suds.transport').removeFilter(
125+
googleads.util.GetSudsTransportFilter())
126+
```
127+
128+
114129
##I'm familiar with suds. Can I use suds features with this library?
115130
Yes, you can. The services returned by the `client.GetService()` functions all
116131
have a reference to the underlying suds client stored in the `suds_client`

examples/adwords/adwords_appengine_demo/handlers/api_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(self, client_id, client_secret, refresh_token,
4545
credentials = GoogleRefreshTokenClient(client_id, client_secret,
4646
refresh_token)
4747
self.client = AdWordsClient(dev_token, credentials, self._USER_AGENT,
48-
manager_account_id)
48+
client_customer_id=manager_account_id)
4949

5050
def AddAdGroup(self, client_customer_id, campaign_id, name, status):
5151
"""Create a new ad group.

examples/adwords/v201605/basic_operations/get_expanded_text_ads.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
"""This example gets all expanded text ads for a given ad group.
1818
19-
To add an ad, run add_text_ads.py.
19+
To add an expanded text ad, run add_expanded_text_ads.py.
2020
2121
The LoadFromStorage method is pulling credentials and properties from a
2222
"googleads.yaml" file. By default, it looks for this file in your home

examples/adwords/v201607/basic_operations/get_expanded_text_ads.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
"""This example gets all expanded text ads for a given ad group.
1818
19-
To add an ad, run add_text_ads.py.
19+
To add an expanded text ad, run add_expanded_text_ads.py.
2020
2121
The LoadFromStorage method is pulling credentials and properties from a
2222
"googleads.yaml" file. By default, it looks for this file in your home
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2016 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Examples for AdWords."""
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2016 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Account management examples."""
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/python
2+
#
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""This example illustrates how to create an account.
18+
19+
Note by default this account will only be accessible via its parent AdWords
20+
manager account..
21+
22+
The LoadFromStorage method is pulling credentials and properties from a
23+
"googleads.yaml" file. By default, it looks for this file in your home
24+
directory. For more information, see the "Caching authentication information"
25+
section of our README.
26+
27+
"""
28+
29+
30+
from datetime import datetime
31+
from googleads import adwords
32+
33+
34+
def main(client):
35+
# Initialize appropriate service.
36+
managed_customer_service = client.GetService(
37+
'ManagedCustomerService', version='v201609')
38+
39+
today = datetime.today().strftime('%Y%m%d %H:%M:%S')
40+
# Construct operations and add campaign.
41+
operations = [{
42+
'operator': 'ADD',
43+
'operand': {
44+
'name': 'Account created with ManagedCustomerService on %s' % today,
45+
'currencyCode': 'EUR',
46+
'dateTimeZone': 'Europe/London',
47+
}
48+
}]
49+
50+
# Create the account. It is possible to create multiple accounts with one
51+
# request by sending an array of operations.
52+
accounts = managed_customer_service.mutate(operations)
53+
54+
# Display results.
55+
for account in accounts['value']:
56+
print ('Account with customer ID \'%s\' was successfully created.'
57+
% account['customerId'])
58+
59+
60+
if __name__ == '__main__':
61+
# Initialize client object.
62+
adwords_client = adwords.AdWordsClient.LoadFromStorage()
63+
main(adwords_client)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/python
2+
#
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""This example gets the changes in the account during the last 24 hours.
18+
19+
The LoadFromStorage method is pulling credentials and properties from a
20+
"googleads.yaml" file. By default, it looks for this file in your home
21+
directory. For more information, see the "Caching authentication information"
22+
section of our README.
23+
24+
"""
25+
26+
27+
import datetime
28+
from googleads import adwords
29+
30+
31+
def main(client):
32+
# Initialize appropriate service.
33+
customer_sync_service = client.GetService(
34+
'CustomerSyncService', version='v201609')
35+
campaign_service = client.GetService('CampaignService', version='v201609')
36+
37+
# Construct selector and get all campaigns.
38+
selector = {
39+
'fields': ['Id', 'Name', 'Status']
40+
}
41+
campaigns = campaign_service.get(selector)
42+
campaign_ids = []
43+
if 'entries' in campaigns:
44+
for campaign in campaigns['entries']:
45+
campaign_ids.append(campaign['id'])
46+
else:
47+
print 'No campaigns were found.'
48+
return
49+
50+
# Construct selector and get all changes.
51+
today = datetime.datetime.today()
52+
yesterday = today - datetime.timedelta(1)
53+
selector = {
54+
'dateTimeRange': {
55+
'min': yesterday.strftime('%Y%m%d %H%M%S'),
56+
'max': today.strftime('%Y%m%d %H%M%S')
57+
},
58+
'campaignIds': campaign_ids
59+
}
60+
account_changes = customer_sync_service.get(selector)
61+
62+
# Display results.
63+
if account_changes:
64+
if 'lastChangeTimestamp' in account_changes:
65+
print 'Most recent changes: %s' % account_changes['lastChangeTimestamp']
66+
if account_changes['changedCampaigns']:
67+
for data in account_changes['changedCampaigns']:
68+
print ('Campaign with id \'%s\' has change status \'%s\'.'
69+
% (data['campaignId'], data['campaignChangeStatus']))
70+
if (data['campaignChangeStatus'] != 'NEW' and
71+
data['campaignChangeStatus'] != 'FIELDS_UNCHANGED'):
72+
if 'addedCampaignCriteria' in data:
73+
print (' Added campaign criteria: %s' %
74+
data['addedCampaignCriteria'])
75+
if 'removedCampaignCriteria' in data:
76+
print (' Removed campaign criteria: %s' %
77+
data['removedCampaignCriteria'])
78+
if 'changedAdGroups' in data:
79+
for ad_group_data in data['changedAdGroups']:
80+
print (' Ad group with id \'%s\' has change status \'%s\'.'
81+
% (ad_group_data['adGroupId'],
82+
ad_group_data['adGroupChangeStatus']))
83+
if ad_group_data['adGroupChangeStatus'] != 'NEW':
84+
if 'changedAds' in ad_group_data:
85+
print ' Changed ads: %s' % ad_group_data['changedAds']
86+
if 'changedCriteria' in ad_group_data:
87+
print (' Changed criteria: %s' %
88+
ad_group_data['changedCriteria'])
89+
if 'removedCriteria' in ad_group_data:
90+
print (' Removed criteria: %s' %
91+
ad_group_data['removedCriteria'])
92+
else:
93+
print 'No changes were found.'
94+
95+
96+
if __name__ == '__main__':
97+
# Initialize client object.
98+
adwords_client = adwords.AdWordsClient.LoadFromStorage()
99+
main(adwords_client)
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/python
2+
#
3+
# Copyright 2016 Google Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""This example gets the account hierarchy under the current account.
18+
19+
The LoadFromStorage method is pulling credentials and properties from a
20+
"googleads.yaml" file. By default, it looks for this file in your home
21+
directory. For more information, see the "Caching authentication information"
22+
section of our README.
23+
24+
"""
25+
from googleads import adwords
26+
27+
28+
PAGE_SIZE = 500
29+
30+
31+
def DisplayAccountTree(account, accounts, links, depth=0):
32+
"""Displays an account tree.
33+
34+
Args:
35+
account: dict The account to display.
36+
accounts: dict Map from customerId to account.
37+
links: dict Map from customerId to child links.
38+
depth: int Depth of the current account in the tree.
39+
"""
40+
prefix = '-' * depth * 2
41+
print '%s%s, %s' % (prefix, account['customerId'], account['name'])
42+
if account['customerId'] in links:
43+
for child_link in links[account['customerId']]:
44+
child_account = accounts[child_link['clientCustomerId']]
45+
DisplayAccountTree(child_account, accounts, links, depth + 1)
46+
47+
48+
def main(client):
49+
# Initialize appropriate service.
50+
managed_customer_service = client.GetService(
51+
'ManagedCustomerService', version='v201609')
52+
53+
# Construct selector to get all accounts.
54+
offset = 0
55+
selector = {
56+
'fields': ['CustomerId', 'Name'],
57+
'paging': {
58+
'startIndex': str(offset),
59+
'numberResults': str(PAGE_SIZE)
60+
}
61+
}
62+
more_pages = True
63+
accounts = {}
64+
child_links = {}
65+
parent_links = {}
66+
root_account = None
67+
68+
while more_pages:
69+
# Get serviced account graph.
70+
page = managed_customer_service.get(selector)
71+
if 'entries' in page and page['entries']:
72+
# Create map from customerId to parent and child links.
73+
if 'links' in page:
74+
for link in page['links']:
75+
if link['managerCustomerId'] not in child_links:
76+
child_links[link['managerCustomerId']] = []
77+
child_links[link['managerCustomerId']].append(link)
78+
if link['clientCustomerId'] not in parent_links:
79+
parent_links[link['clientCustomerId']] = []
80+
parent_links[link['clientCustomerId']].append(link)
81+
# Map from customerID to account.
82+
for account in page['entries']:
83+
accounts[account['customerId']] = account
84+
offset += PAGE_SIZE
85+
selector['paging']['startIndex'] = str(offset)
86+
more_pages = offset < int(page['totalNumEntries'])
87+
88+
# Find the root account.
89+
for customer_id in accounts:
90+
if customer_id not in parent_links:
91+
root_account = accounts[customer_id]
92+
93+
# Display account tree.
94+
if root_account:
95+
print 'CustomerId, Name'
96+
DisplayAccountTree(root_account, accounts, child_links, 0)
97+
else:
98+
print 'Unable to determine a root account'
99+
100+
101+
if __name__ == '__main__':
102+
# Initialize client object.
103+
adwords_client = adwords.AdWordsClient.LoadFromStorage()
104+
main(adwords_client)

0 commit comments

Comments
 (0)