Extensions Samples

The code samples below provide examples of common extension functions using the AdWords API. Client Library.

Add Google My Business location extensions

#!/usr/bin/env python
#
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""Adds a feed that syncs feed items from a Google My Business (GMB) account.

This example associates the feed with a customer.

The LoadFromStorage method is pulling credentials and properties from a
"googleads.yaml" file. By default, it looks for this file in your home
directory. For more information, see the "Caching authentication information"
section of our README.

"""


import time
import uuid

# Import appropriate modules from the client library.
import suds

from googleads import adwords
from googleads import errors

GMB_EMAIL_ADDRESS = 'INSERT_GMB_EMAIL_ADDRESS_HERE'

# If the gmb_email_address above is for a GMB manager instead of
# the GMB account owner, then set business_account_identifier to the
# +Page ID of a location for which the manager has access. See the
# location extensions guide at
# https://developers.google.com/adwords/api/docs/guides/feed-services-locations
# for details.
BUSINESS_ACCOUNT_IDENTIFIER = None

# The placeholder type for location extensions.
# See the Placeholder reference page for a list of all the placeholder types
# and fields:
# https://developers.google.com/adwords/api/docs/appendix/placeholders
PLACEHOLDER_LOCATION = 7

# The maximum number of CustomerFeed ADD operation attempts to make before
# throwing an exception.
MAX_CUSTOMER_FEED_ADD_ATTEMPTS = 10


def main(client, gmb_email_address, gmb_access_token,
         business_account_identifier=None):
  # Create a feed that will sync to the Google Places account specified by
  # gmb_email_address. Do not add FeedAttributes to this object,
  # as AdWords will add them automatically because this will be a
  # system generated feed.
  feed = {
      'name': 'GMB feed #%s' % uuid.uuid4(),
      'systemFeedGenerationData': {
          'xsi_type': 'PlacesLocationFeedData',
          'oAuthInfo': {
              'httpMethod': 'GET',
              'httpRequestUrl': 'https://www.googleapis.com/auth/adwords',
              'httpAuthorizationHeader': 'Bearer %s' % gmb_access_token
          },
          'emailAddress': gmb_email_address,
      },
      # Since this feed's feed items will be managed by AdWords, you must set
      # its origin to ADWORDS.
      'origin': 'ADWORDS'
  }

  # Only include the business_account_identifier if it's specified.
  if business_account_identifier:
    feed['systemFeedGenerationData']['businessAccountIdentifier'] = (
        business_account_identifier
    )

  # Create an operation to add the feed.
  gmb_operations = [{
      'operator': 'ADD',
      'operand': feed
  }]

  gmb_response = client.GetService('FeedService', version='v201710').mutate(
      gmb_operations)
  added_feed = gmb_response['value'][0]
  print 'Added GMB feed with ID: %d\n' % added_feed['id']

  # Add a CustomerFeed that associates the feed with this customer for the
  # LOCATION placeholder type.
  customer_feed = {
      'feedId': added_feed['id'],
      'placeholderTypes': [PLACEHOLDER_LOCATION],
      # Create a matching function that will always evaluate to True.
      'matchingFunction': {
          'operator': 'IDENTITY',
          'lhsOperand': {
              'xsi_type': 'ConstantOperand',
              'type': 'BOOLEAN',
              'booleanValue': True
          }
      }
  }

  customer_feed_operation = {
      'xsi_type': 'CustomerFeedOperation',
      'operator': 'ADD',
      'operand': customer_feed
  }

  customer_feed_service = client.GetService(
      'CustomerFeedService', version='v201710')
  added_customer_feed = None

  i = 0
  while i < MAX_CUSTOMER_FEED_ADD_ATTEMPTS and added_customer_feed is None:
    try:
      added_customer_feed = customer_feed_service.mutate([
          customer_feed_operation])['value'][0]
    except suds.WebFault:
      # Wait using exponential backoff policy
      sleep_seconds = 2 ** i
      print ('Attempt %d to add the CustomerFeed was not successful.'
             'Waiting %d seconds before trying again.\n' % (i, sleep_seconds))

      time.sleep(sleep_seconds)
    i += 1

  if added_customer_feed is None:
    raise errors.GoogleAdsError(
        'Could not create the CustomerFeed after %s attempts. Please retry the '
        'CustomerFeed ADD operation later.' % MAX_CUSTOMER_FEED_ADD_ATTEMPTS)

  print ('Added CustomerFeed for feed ID %d and placeholder type %d\n'
         % (added_customer_feed['id'], added_customer_feed['placeholderTypes']))

if __name__ == '__main__':
  # Initialize client object.
  adwords_client = adwords.AdWordsClient.LoadFromStorage()

  # If the GMB_EMAIL_ADDRESS above is the same user you used to generate your
  # AdWords API refresh token, leave the assignment below unchanged. Otherwise,
  # to obtain an access token for your GMB account, you can run the
  # generate_refresh_token.py example after manually replacing the scope with
  # "https://www.google.com/local/add".
  GMB_ACCESS_TOKEN = adwords_client.oauth2_client.oauth2credentials.access_token

  main(adwords_client, GMB_EMAIL_ADDRESS, GMB_ACCESS_TOKEN,
       BUSINESS_ACCOUNT_IDENTIFIER)

Add prices

#!/usr/bin/env python
#
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""Adds a price extension and associates it with an account.

Campaign targeting is also set usin the specified campaign ID. To get campaigns,
run get_campaigns.py.

The LoadFromStorage method is pulling credentials and properties from a
"googleads.yaml" file. By default, it looks for this file in your home
directory. For more information, see the "Caching authentication information"
section of our README.

"""

from googleads import adwords
from googleads import errors


CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE'
MICROS_PER_DOLLAR = 1000000


def main(client, campaign_id):
  # Initialize appropriate service.
  customer_extension_setting_service = client.GetService(
      'CustomerExtensionSettingService', 'v201710')

  # To create a price extension, at least three table rows are needed.
  table_rows = [
      CreatePriceTableRow('Scrubs', 'Body Scrub, Salt Scrub',
                          'https://www.example.com/scrubs',
                          60 * MICROS_PER_DOLLAR, 'USD', 'PER_HOUR',
                          final_mobile_url='http://m.example.com/scrubs'),
      CreatePriceTableRow('Hair Cuts', 'Once a month',
                          'https://www.example.com/haircuts',
                          75 * MICROS_PER_DOLLAR, 'USD', 'PER_MONTH',
                          final_mobile_url='http://m.example.com/haircuts'),
      CreatePriceTableRow('Skin Care Package', 'Four times a month',
                          'https://www.examples.com/skincarepackage',
                          250 * MICROS_PER_DOLLAR, 'USD', 'PER_MONTH',
                          final_mobile_url=(
                              'http://m.example.com/skincarepackage'))
  ]

  # Create the price extension feed item.
  customer_extension_setting = {
      'extensionType': 'PRICE',
      'extensionSetting': {
          'extensions': [{
              'priceExtensionType': 'SERVICES',
              'trackingUrlTemplate': 'http://tracker.example.com/?u={lpurl}',
              'language': 'en',
              'campaignTargeting': {
                  'TargetingCampaignId': campaign_id
              },
              'scheduling': {
                  'feedItemSchedules': [
                      {
                          'dayOfWeek': 'SATURDAY',
                          'startHour': 10,
                          'startMinute': 'ZERO',
                          'endHour': 22,
                          'endMinute': 'ZERO'
                      },
                      {
                          'dayOfWeek': 'SUNDAY',
                          'startHour': 10,
                          'startMinute': 'ZERO',
                          'endHour': 18,
                          'endMinute': 'ZERO'
                      }
                  ]
              },
              'tableRows': table_rows,
              # Price qualifier is optional.
              'priceQualifier': 'FROM',
              'xsi_type': 'PriceFeedItem'
          }]
      }
  }

  # Create an operation to add the feed.
  operations = [{
      'operator': 'ADD',
      'operand': customer_extension_setting
  }]

  # Add the price extension.
  response = customer_extension_setting_service.mutate(operations)

  # Print the results.
  if 'value' in response:
    print ('Extension setting with type "%s" was added to your account.'
           % response['value'][0]['extensionType'])
  else:
    raise errors.GoogleAdsError('No extension settings were added.')


def CreatePriceTableRow(header, description, final_url, price_in_micros,
                        currency_code, price_unit, final_mobile_url=None):
  """Helper function to generate a single row of a price table.

  Args:
    header: A str containing the header text of this row.
    description: A str description of this row in the price table.
    final_url: A str containing the final URL after all cross domain redirects.
    price_in_micros: An int indicating the price of the given currency in
      micros.
    currency_code: A str indicating the currency code being used.
    price_unit: A str enum indicating the price unit for this row.
    final_mobile_url: A str containing the final mobile URL after all cross
      domain redirects.

  Returns:
    A dictionary containing the contents of the generated price table row.
  """
  table_row = {
      'header': header,
      'description': description,
      'finalUrls': {'urls': [final_url]},
      'price': {
          'money': {
              'microAmount': price_in_micros,
          },
          'currencyCode': currency_code
      },
      'priceUnit': price_unit,
      'xsi_type': 'PriceTableRow'
  }

  if final_mobile_url:
    table_row['finalMobileUrls'] = {
        'urls': [final_mobile_url]
    }

  return table_row


if __name__ == '__main__':
  # Initialize client object.
  adwords_client = adwords.AdWordsClient.LoadFromStorage()
  main(adwords_client, CAMPAIGN_ID)

Add sitelinks to a campaign

#!/usr/bin/env python
#
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Adds sitelinks to a campaign using the CampaignExtensionSettingService.

The LoadFromStorage method is pulling credentials and properties from a
"googleads.yaml" file. By default, it looks for this file in your home
directory. For more information, see the "Caching authentication information"
section of our README.

"""


from datetime import datetime

from googleads import adwords
from googleads import errors
from pytz import timezone

CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE'


def main(client, campaign_id):
  # Initialize appropriate services.
  campaign_extension_setting_service = client.GetService(
      'CampaignExtensionSettingService', version='v201710')
  customer_service = client.GetService('CustomerService', version='v201710')
  # Find the matching customer and its time zone. The getCustomers method will
  # return a single Customer object corresponding to the configured
  # clientCustomerId.
  customer = customer_service.getCustomers()[0]
  customer_tz = timezone(customer['dateTimeZone'])
  time_fmt = '%s %s' % ('%Y%m%d %H%M%S', customer_tz)

  print ('Found customer ID %d with time zone "%s".'
         % (customer['customerId'], customer['dateTimeZone']))

  # Create the sitelinks
  sitelink1 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Store Hours',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/storehours']}
  }

  # Show the Thanksgiving specials link only from 20 - 27 Nov.
  sitelink2 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Thanksgiving Specials',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/thanksgiving']},
      # The time zone of the start and end date/times must match the time zone
      # of the customer.
      'startTime': datetime(datetime.now().year, 11, 20, 0, 0, 0, 0,
                            customer_tz).strftime(time_fmt),
      'endTime': datetime(datetime.now().year, 11, 27, 23, 59, 59, 59,
                          customer_tz).strftime(time_fmt),
      # Target this sitelink for United States only. For valid geolocation
      # codes, see:
      # https://developers.google.com/adwords/api/docs/appendix/geotargeting
      'geoTargeting': {'id': 2840},
      # Restrict targeting only to people physically within the United States.
      # Otherwise, this could also show to people interested in the United
      # States, but not physically located there.
      'geoTargetingRestriction': {
          'geoRestriction': 'LOCATION_OF_PRESENCE'
      }
  }

  # Show the wifi details primarily for high end mobile users.
  sitelink3 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Wifi Available',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/mobile/wifi']},
      # See https://developers.google.com/adwords/api/docs/appendix/platforms
      # for device criteria IDs.
      'devicePreference': {'devicePreference': '30001'},
      # Target this sitelink only when the ad is triggered by the keyword
      # "free wifi."
      'keywordTargeting': {
          'text': 'free wifi',
          'matchType': 'BROAD'
      }
  }

  # Show the happy hours link only during Mon - Fri 6PM to 9PM.
  sitelink4 = {
      'xsi_type': 'SitelinkFeedItem',
      'sitelinkText': 'Happy hours',
      'sitelinkFinalUrls': {'urls': ['http://www.example.com/happyhours']},
      'scheduling': {
          'feedItemSchedules': [
              {
                  'dayOfWeek': day,
                  'startHour': '18',
                  'startMinute': 'ZERO',
                  'endHour': '21',
                  'endMinute': 'ZERO'
              } for day in ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY',
                            'FRIDAY']
          ]
      }
  }

  # Create your Campaign Extension Settings. This associates the sitelinks
  # to your campaign.
  campaign_extension_setting = {
      'campaignId': campaign_id,
      'extensionType': 'SITELINK',
      'extensionSetting': {
          'extensions': [sitelink1, sitelink2, sitelink3, sitelink4]
      }
  }

  operation = {
      'operator': 'ADD',
      'operand': campaign_extension_setting
  }

  # Add the extensions.
  response = campaign_extension_setting_service.mutate([operation])

  if 'value' in response:
    print ('Extension setting with type "%s" was added to campaignId "%d".' %
           (response['value'][0]['extensionType'],
            response['value'][0]['campaignId']))
  else:
    raise errors.GoogleAdsError('No extension settings were added.')


if __name__ == '__main__':
  # Initialize client object.
  adwords_client = adwords.AdWordsClient.LoadFromStorage()

  main(adwords_client, CAMPAIGN_ID)

Add sitelinks to a campaign using feeds

#!/usr/bin/env python
#
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This example adds a sitelinks feed and associates it with a campaign.

To add sitelinks using the simpler ExtensionSetting services, see:
add_sitelinks.py.

The LoadFromStorage method is pulling credentials and properties from a
"googleads.yaml" file. By default, it looks for this file in your home
directory. For more information, see the "Caching authentication information"
section of our README.

"""


import re
import uuid
from googleads import adwords
from googleads import errors

# See the Placeholder reference page for a list of all the placeholder types and
# fields.
# https://developers.google.com/adwords/api/docs/appendix/placeholders.html
PLACEHOLDER_SITELINKS = '1'
PLACEHOLDER_FIELD_SITELINK_LINK_TEXT = '1'
PLACEHOLDER_FIELD_SITELINK_FINAL_URLS = '5'
PLACEHOLDER_FIELD_LINE_2_TEXT = '3'
PLACEHOLDER_FIELD_LINE_3_TEXT = '4'

CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE'


def main(client, campaign_id):
  # Initialize appropriate service.
  feed_service = client.GetService('FeedService', version='v201710')
  feed_item_service = client.GetService('FeedItemService', version='v201710')
  feed_mapping_service = client.GetService(
      'FeedMappingService', version='v201710')
  campaign_feed_service = client.GetService(
      'CampaignFeedService', version='v201710')

  sitelinks_data = {}

  # Create site links feed first.
  site_links_feed = {
      'name': 'Feed For Site Links #%s' % uuid.uuid4(),
      'attributes': [
          {'type': 'STRING', 'name': 'Link Text'},
          {'type': 'URL_LIST', 'name': 'Link Final URLs'},
          {'type': 'STRING', 'name': 'Line 2 Description'},
          {'type': 'STRING', 'name': 'Line 3 Description'}
      ]
  }

  response = feed_service.mutate([
      {'operator': 'ADD', 'operand': site_links_feed}
  ])

  if 'value' in response:
    feed = response['value'][0]
    link_text_feed_attribute_id = feed['attributes'][0]['id']
    final_url_feed_attribute_id = feed['attributes'][1]['id']
    line_2_feed_attribute_id = feed['attributes'][2]['id']
    line_3_feed_attribute_id = feed['attributes'][3]['id']
    print ('Feed with name "%s" and ID "%s" was added with' %
           (feed['name'], feed['id']))
    print ('\tText attribute ID "%s" and Final URL attribute ID "%s".' %
           (link_text_feed_attribute_id, final_url_feed_attribute_id))
    print ('\tLine 2 attribute ID "%s" and Line 3 attribute ID "%s".' %
           (line_2_feed_attribute_id, line_3_feed_attribute_id))
    sitelinks_data['feedId'] = feed['id']
    sitelinks_data['linkTextFeedId'] = link_text_feed_attribute_id
    sitelinks_data['finalUrlFeedId'] = final_url_feed_attribute_id
    sitelinks_data['line2FeedId'] = line_2_feed_attribute_id
    sitelinks_data['line3FeedId'] = line_3_feed_attribute_id
  else:
    raise errors.GoogleAdsError('No feeds were added.')

  # Create site links feed items.
  items_data = [
      {'text': 'Home', 'finalUrls': 'http://www.example.com',
       'line2': 'Home line 2', 'line3': 'Home line 3'},
      {'text': 'Stores', 'finalUrls': 'http://www.example.com/stores',
       'line2': 'Stores line 2', 'line3': 'Stores line 3'},
      {'text': 'On Sale', 'finalUrls': 'http://www.example.com/sale',
       'line2': 'On Sale line 2', 'line3': 'On Sale line 3'},
      {'text': 'Support', 'finalUrls': 'http://www.example.com/support',
       'line2': 'Support line 2', 'line3': 'Support line 3'},
      {'text': 'Products', 'finalUrls': 'http://www.example.com/products',
       'line2': 'Products line 2', 'line3': 'Products line 3'},
      {'text': 'About Us', 'finalUrls': 'http://www.example.com/about',
       'line2': 'About line 2', 'line3': 'About line 3', 'locationId': '21137'}
  ]

  feed_items = []
  for item in items_data:
    feed_item = {
        'feedId': sitelinks_data['feedId'],
        'attributeValues': [
            {
                'feedAttributeId': sitelinks_data['linkTextFeedId'],
                'stringValue': item['text']
            },
            {
                'feedAttributeId': sitelinks_data['finalUrlFeedId'],
                'stringValues': [item['finalUrls']]
            },
            {
                'feedAttributeId': sitelinks_data['line2FeedId'],
                'stringValue': item['line2']
            },
            {
                'feedAttributeId': sitelinks_data['line3FeedId'],
                'stringValue': item['line3']
            }
        ],
        # Optional: use the 'startTime' and 'endTime' keys to specify the time
        # period for the feed to deliver.  The example below will make the feed
        # start now and stop in one month.
        # Make sure you specify the datetime in the customer's time zone. You
        # can retrieve this from customer['dateTimeZone'].
        #
        # ['startTime']: datetime.datetime.now().strftime('%Y%m%d %H%M%S')
        # ['endTime']: (datetime.datetime.now() +
        #               relativedelta(months=1)).strftime('%Y%m%d %H%M%S')
    }

    # Use geographical targeting on a feed.
    # The IDs can be found in the documentation or retrieved with the
    # LocationCriterionService.
    if 'locationId' in item:
      feed_item['geoTargeting'] = {
          'id': item['locationId']
      }
      feed_item['geoTargetingRestriction'] = {
          'geoRestriction': 'LOCATION_OF_PRESENCE'
      }

    feed_items.append(feed_item)

  feed_items_operations = [{'operator': 'ADD', 'operand': item} for item
                           in feed_items]

  response = feed_item_service.mutate(feed_items_operations)
  if 'value' in response:
    sitelinks_data['feedItemIds'] = []
    for feed_item in response['value']:
      print 'Feed item with ID %s was added.' % feed_item['feedItemId']
      sitelinks_data['feedItemIds'].append(feed_item['feedItemId'])
  else:
    raise errors.GoogleAdsError('No feed items were added.')

  # Create site links feed mapping.

  feed_mapping = {
      'placeholderType': PLACEHOLDER_SITELINKS,
      'feedId': sitelinks_data['feedId'],
      'attributeFieldMappings': [
          {
              'feedAttributeId': sitelinks_data['linkTextFeedId'],
              'fieldId': PLACEHOLDER_FIELD_SITELINK_LINK_TEXT
          },
          {
              'feedAttributeId': sitelinks_data['finalUrlFeedId'],
              'fieldId': PLACEHOLDER_FIELD_SITELINK_FINAL_URLS
          },
          {
              'feedAttributeId': sitelinks_data['line2FeedId'],
              'fieldId': PLACEHOLDER_FIELD_LINE_2_TEXT
          },
          {
              'feedAttributeId': sitelinks_data['line3FeedId'],
              'fieldId': PLACEHOLDER_FIELD_LINE_3_TEXT
          }
      ]
  }

  response = feed_mapping_service.mutate([
      {'operator': 'ADD', 'operand': feed_mapping}
  ])
  if 'value' in response:
    feed_mapping = response['value'][0]
    print ('Feed mapping with ID %s and placeholder type %s was saved for feed'
           ' with ID %s.' %
           (feed_mapping['feedMappingId'], feed_mapping['placeholderType'],
            feed_mapping['feedId']))
  else:
    raise errors.GoogleAdsError('No feed mappings were added.')

  # Construct a matching function that associates the sitelink feeditems to the
  # campaign, and set the device preference to Mobile. For more details, see the
  # matching function guide:
  # https://developers.google.com/adwords/api/docs/guides/feed-matching-functions
  matching_function_string = (
      'AND(IN(FEED_ITEM_ID, {%s}), EQUALS(CONTEXT.DEVICE, \'Mobile\'))' %
      re.sub(r'\[|\]|L', '', str(sitelinks_data['feedItemIds'])))

  campaign_feed = {
      'feedId': sitelinks_data['feedId'],
      'campaignId': campaign_id,
      'matchingFunction': {'functionString': matching_function_string},
      # Specifying placeholder types on the CampaignFeed allows the same feed
      # to be used for different placeholders in different Campaigns.
      'placeholderTypes': [PLACEHOLDER_SITELINKS]
  }

  response = campaign_feed_service.mutate([
      {'operator': 'ADD', 'operand': campaign_feed}
  ])
  if 'value' in response:
    campaign_feed = response['value'][0]
    print ('Campaign with ID %s was associated with feed with ID %s.' %
           (campaign_feed['campaignId'], campaign_feed['feedId']))
  else:
    raise errors.GoogleAdsError('No campaign feeds were added.')


if __name__ == '__main__':
  # Initialize client object.
  adwords_client = adwords.AdWordsClient.LoadFromStorage()

  main(adwords_client, CAMPAIGN_ID)

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.