Campaign Management Samples

The code samples below provide examples for managing campaigns using the AdWords API. Client Library.

Add a campaign group and sets a performance target for that group

#!/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 campaign group and sets a performance target for it.

To get campaigns, run get_campaigns.py. To download reports, run
download_criteria_report_with_awql.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 datetime
import uuid
from googleads import adwords


CAMPAIGN_ID1 = 'INSERT_FIRST_CAMPAIGN_ID_HERE'
CAMPAIGN_ID2 = 'INSERT_SECOND_CAMPAIGN_ID_HERE'


def main(client, campaign_id1, campaign_id2):
  campaign_group_id = _CreateCampaignGroup(client)
  _AddCampaignsToGroup(client, campaign_group_id, [campaign_id1, campaign_id2])
  _CreatePerformanceTarget(client, campaign_group_id)
  print 'Campaign group and its performance target were setup successfully.'


def _CreateCampaignGroup(client):
  """Create a campaign group.

  Args:
    client: an AdWordsClient instance.

  Returns:
    The integer ID of the created campaign group.
  """
  # Get the CampaignGroupService.
  campaign_group_service = client.GetService('CampaignGroupService',
                                             version='v201705')

  # Create the operation.
  operations = [{
      'operator': 'ADD',
      # Create the campaign group.
      'operand': {
          'name': 'Mars campaign group #%d' % uuid.uuid4()
      }
  }]

  campaign_group = campaign_group_service.mutate(operations)['value'][0]
  campaign_group_id = campaign_group['id']

  # Display the results.
  print 'Campaign group with ID "%d" and name "%s" was created.' % (
      campaign_group_id, campaign_group['name'])

  return campaign_group_id


def _AddCampaignsToGroup(client, campaign_group_id, campaign_ids):
  """Adds multiple campaigns to a campaign group.

  Args:
    client: an AdWordsClient instance.
    campaign_group_id: an integer ID for the campaign group.
    campaign_ids: a list of integer IDs for campaigns.
  """
  # Get the CampaignService.
  campaign_service = client.GetService('CampaignService', version='v201705')

  # Create the operations.
  operations = [{
      'operator': 'SET',
      'operand': {
          'id': campaign_id,
          'campaignGroupId': campaign_group_id
      }
  } for campaign_id in campaign_ids]

  campaign_service.mutate(operations)

  # Display the results.
  print ('The following campaign IDs were added to the campaign group with ID '
         '"%d":\n\t%s' % (campaign_group_id, campaign_ids))


def _CreatePerformanceTarget(client, campaign_group_id):
  """Creates a performance target for the campaign group.

  Args:
    client: an AdWordsClient instance.
    campaign_group_id: an integer ID for the campaign group.
  """
  # Get the CampaignGroupPerformanceTargetService.
  cgpt_service = client.GetService('CampaignGroupPerformanceTargetService',
                                   version='v201705')

  # Create the operation.
  operations = [{
      'operator': 'ADD',
      # Create the performance target.
      'operand': {
          'campaignGroupId': campaign_group_id,
          'performanceTarget': {
              # Keep the CPC for the campaigns < $3.
              'efficiencyTargetType': 'CPC_LESS_THAN_OR_EQUAL_TO',
              'efficiencyTargetValue': 3000000,
              # Keep the maximum spend under $50.
              'spendTargetType': 'MAXIMUM',
              'spendTarget': {
                  'microAmount': 500000000
              },
              # Aim for at least 3000 clicks.
              'volumeGoalType': 'MAXIMIZE_CLICKS',
              'volumeTargetValue': 3000,
              # Start the performance target today, and run it for the next 90
              # days.
              'startDate': datetime.datetime.now().strftime('%Y%m%d'),
              'endDate': (datetime.datetime.now() +
                          datetime.timedelta(90)).strftime('%Y%m%d')
          }
      }
  }]

  cgpt = cgpt_service.mutate(operations)['value'][0]

  # Display the results.
  print ('Campaign performance target with ID "%d" was added for campaign '
         'group ID "%d".' % (cgpt['id'], cgpt['campaignGroupId']))


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

  main(adwords_client, CAMPAIGN_ID1, CAMPAIGN_ID2)

Add a label to multiple campaigns

#!/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 label to multiple campaigns.

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


CAMPAIGN_ID1 = 'INSERT_FIRST_CAMPAIGN_ID_HERE'
CAMPAIGN_ID2 = 'INSERT_SECOND_CAMPAIGN_ID_HERE'
LABEL_ID = 'INSERT_LABEL_ID_HERE'


def main(client, campaign_id1, campaign_id2, label_id):
  # Initialize appropriate service.
  campaign_service = client.GetService('CampaignService', version='v201705')

  operations = [
      {
          'operator': 'ADD',
          'operand': {
              'campaignId': campaign_id1,
              'labelId': label_id,
          }
      },
      {
          'operator': 'ADD',
          'operand': {
              'campaignId': campaign_id2,
              'labelId': label_id,
          }
      }
  ]

  result = campaign_service.mutateLabel(operations)

  # Display results.
  for label in result['value']:
    print ('CampaignLabel with campaignId \'%s\' and labelId \'%s\' was added.'
           % (label['campaignId'], label['labelId']))


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

  main(adwords_client, CAMPAIGN_ID1, CAMPAIGN_ID2, LABEL_ID)

Add a draft

#!/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.

"""Creates a draft and accesses its associated draft campaign.

See the Campaign Drafts and Experiments guide for more information:
https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments

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 uuid
from googleads import adwords


BASE_CAMPAIGN_ID = 'INSERT_BASE_CAMPAIGN_ID_HERE'


def main(client, base_campaign_id):
  draft_service = client.GetService('DraftService', version='v201705')

  draft = {
      'baseCampaignId': base_campaign_id,
      'draftName': 'Test Draft #%s' % uuid.uuid4()
  }

  draft_operation = {'operator': 'ADD', 'operand': draft}
  draft = draft_service.mutate([draft_operation])['value'][0]
  draft_campaign_id = draft['draftCampaignId']

  # Once the draft is created, you can modify the draft campaign as if it were a
  # real campaign. For example, you may add criteria, adjust bids, or even
  # include additional ads. Adding a criteria is shown here.
  campaign_criterion_service = client.GetService('CampaignCriterionService',
                                                 version='v201705')

  criterion = {
      'xsi_type': 'Language',
      'id': 1003  # Spanish
  }

  criterion_operation = {
      # Make sure to use the draftCampaignId when modifying the virtual draft
      # campaign.
      'operator': 'ADD',
      'operand': {
          'campaignId': draft_campaign_id,
          'criterion': criterion
      }
  }

  criterion = campaign_criterion_service.mutate([criterion_operation])[
      'value'][0]

  print ('Draft updated to include criteria in campaign with ID %d' %
         draft_campaign_id)


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

  main(adwords_client, BASE_CAMPAIGN_ID)

Add keywords using an incremental batch job

#!/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 uses the BatchJobService to incrementally create a complete Campaign.

The complete Campaign created by this example also includes AdGroups and
KeyWords.

"""

import random
import time
import urllib2
import uuid

from googleads import adwords


ADGROUP_ID = 'INSERT_ADGROUP_ID_HERE'
KEYWORD_COUNT = 100
MAX_POLL_ATTEMPTS = 5
PENDING_STATUSES = ('ACTIVE', 'AWAITING_FILE', 'CANCELING')


def main(client, adgroup_id):
  # Initialize BatchJobHelper.
  batch_job_helper = client.GetBatchJobHelper(version='v201705')
  # Create a BatchJob.
  batch_job = AddBatchJob(client)

  # Retrieve the URL used to upload the BatchJob operations.
  upload_url = batch_job['uploadUrl']['url']
  batch_job_id = batch_job['id']
  print 'Created BatchJob with ID "%d", status "%s", and upload URL "%s"' % (
      batch_job['id'], batch_job['status'], upload_url)

  # Initialize IncrementalUploadHelper.
  incremental_uploader = batch_job_helper.GetIncrementalUploadHelper(upload_url)

  # Generate and upload first set of operations.
  adgroup_criterion_operations = BuildAdGroupCriterionOperations(adgroup_id)
  incremental_uploader.UploadOperations(
      [adgroup_criterion_operations])
  # Generate and upload second set of operations.
  adgroup_criterion_operations = BuildAdGroupCriterionOperations(adgroup_id)
  incremental_uploader.UploadOperations(
      [adgroup_criterion_operations])
  # Generate and upload third and final set of operations.
  adgroup_criterion_operations = BuildAdGroupCriterionOperations(adgroup_id)
  incremental_uploader.UploadOperations(
      [adgroup_criterion_operations], is_last=True)

  # Download and display results.
  download_url = GetBatchJobDownloadUrlWhenReady(client, batch_job_id)
  response = urllib2.urlopen(download_url).read()
  PrintResponse(batch_job_helper, response)


def AddBatchJob(client):
  """Add a new BatchJob to upload operations to.

  Args:
    client: an instantiated AdWordsClient used to retrieve the BatchJob.

  Returns:
    The new BatchJob created by the request.
  """
  # Initialize appropriate service.
  batch_job_service = client.GetService('BatchJobService', version='v201705')
  # Create a BatchJob.
  batch_job_operations = [{
      'operand': {},
      'operator': 'ADD'
  }]
  return batch_job_service.mutate(batch_job_operations)['value'][0]


def BuildAdGroupCriterionOperations(adgroup_id):
  """Builds the operations adding a Keyword Criterion to each AdGroup.

  Args:
    adgroup_id: an integer identifying an AdGroup to associate the keywords
      with.

  Returns:
    a list containing the operations that will create a new Keyword Criterion
    associated with each provided AdGroup.
  """
  criterion_operations = [
      {
          # You must specify the xsi_type of operations run by the
          # BatchJobService.
          'xsi_type': 'AdGroupCriterionOperation',
          'operand': {
              'xsi_type': 'BiddableAdGroupCriterion',
              'adGroupId': adgroup_id,
              'criterion': {
                  'xsi_type': 'Keyword',
                  # Make 10% of keywords invalid to demonstrate error handling.
                  'text': 'mars%s%s' % (uuid.uuid4(),
                                        '!!!' if i % 10 == 0 else ''),
                  'matchType': 'BROAD'
              }
          },
          'operator': 'ADD'
      }
      for i in range(KEYWORD_COUNT)]

  return criterion_operations


def CancelBatchJob(client, batch_job, max_poll_attempts=MAX_POLL_ATTEMPTS):
  """Cancels the given BatchJob.

  Args:
    client: an instantiated AdWordsClient used to cancel the BatchJob.
    batch_job: a BatchJob to be canceled.
    max_poll_attempts: an int defining the number of times the the BatchJob will
      be checked to determine whether it has been canceled.
  """
  batch_job_service = client.GetService('BatchJobService', 'v201705')
  batch_job['status'] = 'CANCELING'

  operation = {
      'operator': 'SET',
      'operand': batch_job
  }

  batch_job_service.mutate([operation])

  # Verify that the Batch Job cancels.
  poll_attempt = 0

  while (poll_attempt in range(max_poll_attempts) and
         batch_job['status'] != 'CANCELED'):
    sleep_interval = (30 * (2 ** poll_attempt) +
                      (random.randint(0, 10000) / 1000))
    print ('Batch Job not finished canceling, sleeping for %s seconds.'
           % sleep_interval)
    time.sleep(sleep_interval)
    batch_job = GetBatchJob(client, batch_job['id'])
    poll_attempt += 1

  if batch_job['status'] == 'CANCELED':
    print ('Batch Job with ID "%d" has been successfully canceled.' %
           batch_job['id'])
  else:
    print ('Batch Job with ID "%d" failed to cancel after polling %d times.'
           % (batch_job['id'], max_poll_attempts))


def GetBatchJob(client, batch_job_id):
  """Retrieves the BatchJob with the given id.

  Args:
    client: an instantiated AdWordsClient used to retrieve the BatchJob.
    batch_job_id: a long identifying the BatchJob to be retrieved.
  Returns:
    The BatchJob associated with the given id.
  """
  batch_job_service = client.GetService('BatchJobService', 'v201705')

  selector = {
      'fields': ['Id', 'Status', 'DownloadUrl'],
      'predicates': [
          {
              'field': 'Id',
              'operator': 'EQUALS',
              'values': [batch_job_id]
          }
      ]
  }

  return batch_job_service.get(selector)['entries'][0]


def GetBatchJobDownloadUrlWhenReady(client, batch_job_id,
                                    max_poll_attempts=MAX_POLL_ATTEMPTS):
  """Retrieves the downloadUrl when the BatchJob is complete.

  Args:
    client: an instantiated AdWordsClient used to poll the BatchJob.
    batch_job_id: a long identifying the BatchJob to be polled.
    max_poll_attempts: an int defining the number of times the the BatchJob will
      be checked to determine whether it has completed.

  Returns:
    A str containing the downloadUrl of the completed BatchJob.

  Raises:
    Exception: If the BatchJob hasn't finished after the maximum poll attempts
      have been made.
  """
  batch_job = GetBatchJob(client, batch_job_id)
  if batch_job['status'] == 'CANCELED':
    raise Exception('Batch Job with ID "%s" was canceled before completing.'
                    % batch_job_id)

  poll_attempt = 0

  while (poll_attempt in range(max_poll_attempts) and
         batch_job['status'] in PENDING_STATUSES):
    sleep_interval = (30 * (2 ** poll_attempt) +
                      (random.randint(0, 10000) / 1000))
    print 'Batch Job not ready, sleeping for %s seconds.' % sleep_interval
    time.sleep(sleep_interval)
    batch_job = GetBatchJob(client, batch_job_id)
    poll_attempt += 1

    if 'downloadUrl' in batch_job:
      url = batch_job['downloadUrl']['url']
      print ('Batch Job with Id "%s", Status "%s", and DownloadUrl "%s" ready.'
             % (batch_job['id'], batch_job['status'], url))
      return url

  print ('BatchJob with ID "%s" is being canceled because it was in a pending '
         'state after polling %d times.' % (batch_job_id, max_poll_attempts))
  CancelBatchJob(client, batch_job)


def PrintResponse(batch_job_helper, response_xml):
  """Prints the BatchJobService response.

  Args:
    batch_job_helper: a BatchJobHelper instance.
    response_xml: a string containing a response from the BatchJobService.
  """
  response = batch_job_helper.ParseResponse(response_xml)

  if 'rval' in response['mutateResponse']:
    for data in response['mutateResponse']['rval']:
      if 'errorList' in data:
        print 'Operation %s - FAILURE:' % data['index']
        print '\terrorType=%s' % data['errorList']['errors']['ApiError.Type']
        print '\ttrigger=%s' % data['errorList']['errors']['trigger']
        print '\terrorString=%s' % data['errorList']['errors']['errorString']
        print '\tfieldPath=%s' % data['errorList']['errors']['fieldPath']
        print '\treason=%s' % data['errorList']['errors']['reason']
      if 'result' in data:
        print 'Operation %s - SUCCESS.' % data['index']


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

Add complete campaigns using batch jobs

#!/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 uses the BatchJobService to create a complete Campaign.

The complete Campaign created by this example also includes AdGroups and
KeyWords.

"""

import random
import time
import urllib2
import uuid

from googleads import adwords


NUMBER_OF_CAMPAIGNS_TO_ADD = 2
NUMBER_OF_ADGROUPS_TO_ADD = 2
NUMBER_OF_KEYWORDS_TO_ADD = 5
MAX_POLL_ATTEMPTS = 5
PENDING_STATUSES = ('ACTIVE', 'AWAITING_FILE', 'CANCELING')


def main(client, number_of_campaigns, number_of_adgroups, number_of_keywords):
  # Initialize BatchJobHelper.
  batch_job_helper = client.GetBatchJobHelper(version='v201705')

  # Create a BatchJob.
  batch_job = AddBatchJob(client)
  # Retrieve the URL used to upload the BatchJob operations.
  upload_url = batch_job['uploadUrl']['url']
  batch_job_id = batch_job['id']
  print 'Created BatchJob with ID "%d", status "%s", and upload URL "%s"' % (
      batch_job['id'], batch_job['status'], upload_url)

  # Generate operations to upload.
  budget_operations = BuildBudgetOperations(batch_job_helper)
  campaign_operations = BuildCampaignOperations(
      batch_job_helper, budget_operations, number_of_campaigns)
  campaign_criterion_operations = BuildCampaignCriterionOperations(
      campaign_operations)
  adgroup_operations = BuildAdGroupOperations(
      batch_job_helper, campaign_operations, number_of_adgroups)
  adgroup_criterion_operations = BuildAdGroupCriterionOperations(
      adgroup_operations, number_of_keywords)
  adgroup_ad_operations = BuildAdGroupAdOperations(adgroup_operations)

  # Upload operations.
  batch_job_helper.UploadOperations(
      upload_url, budget_operations, campaign_operations,
      campaign_criterion_operations, adgroup_operations,
      adgroup_criterion_operations, adgroup_ad_operations)

  # Download and display results.
  download_url = GetBatchJobDownloadUrlWhenReady(client, batch_job_id)
  response = urllib2.urlopen(download_url).read()
  PrintResponse(batch_job_helper, response)


def AddBatchJob(client):
  """Add a new BatchJob to upload operations to.

  Args:
    client: an instantiated AdWordsClient used to retrieve the BatchJob.

  Returns:
    The new BatchJob created by the request.
  """
  # Initialize appropriate service.
  batch_job_service = client.GetService('BatchJobService', version='v201705')
  # Create a BatchJob.
  batch_job_operations = [{
      'operand': {},
      'operator': 'ADD'
  }]
  return batch_job_service.mutate(batch_job_operations)['value'][0]


def BuildAdGroupAdOperations(adgroup_operations):
  """Builds the operations adding an ExpandedTextAd to each AdGroup.

  Args:
    adgroup_operations: a list containing the operations that will add AdGroups.

  Returns:
    a list containing the operations that will create a new ExpandedTextAd for
    each of the provided AdGroups.
  """
  adgroup_ad_operations = [
      {
          # The xsi_type of the operation can usually be guessed by the API
          # because a given service only handles one type of operation.
          # However, batch jobs process operations of different types, so
          # the xsi_type must always be explicitly defined for these
          # operations.
          'xsi_type': 'AdGroupAdOperation',
          'operand': {
              'adGroupId': adgroup_operation['operand']['id'],
              'ad': {
                  'xsi_type': 'ExpandedTextAd',
                  'headlinePart1': 'Luxury Cruise to Mars',
                  'headlinePart2': 'Visit the Red Planet in style.',
                  'description': 'Low-gravity fun for everyone!',
                  'finalUrls': ['http://www.example.com/1']
              }
          },
          'operator': 'ADD'
      }
      for adgroup_operation in adgroup_operations]

  return adgroup_ad_operations


def BuildAdGroupCriterionOperations(adgroup_operations, number_of_keywords=1):
  """Builds the operations adding a Keyword Criterion to each AdGroup.

  Args:
    adgroup_operations: a list containing the operations that will add AdGroups.
    number_of_keywords: an int defining the number of Keywords to be created.

  Returns:
    a list containing the operations that will create a new Keyword Criterion
    associated with each provided AdGroup.
  """
  criterion_operations = [
      {
          # The xsi_type of the operation can usually be guessed by the API
          # because a given service only handles one type of operation.
          # However, batch jobs process operations of different types, so
          # the xsi_type must always be explicitly defined for these
          # operations.
          'xsi_type': 'AdGroupCriterionOperation',
          'operand': {
              'xsi_type': 'BiddableAdGroupCriterion',
              'adGroupId': adgroup_operation['operand']['id'],
              'criterion': {
                  'xsi_type': 'Keyword',
                  # Make 50% of keywords invalid to demonstrate error handling.
                  'text': 'mars%s%s' % (i, '!!!' if i % 2 == 0 else ''),
                  'matchType': 'BROAD'
              }
          },
          'operator': 'ADD'
      }
      for adgroup_operation in adgroup_operations
      for i in range(number_of_keywords)]

  return criterion_operations


def BuildAdGroupOperations(batch_job_helper,
                           campaign_operations, number_of_adgroups=1):
  """Builds the operations adding desired number of AdGroups to given Campaigns.

  Note: When the AdGroups are created, they will have a different Id than those
  generated here as a temporary Id. This is just used to identify them in the
  BatchJobService.

  Args:
    batch_job_helper: a BatchJobHelper instance.
    campaign_operations: a list containing the operations that will add
      Campaigns.
    number_of_adgroups: an int defining the number of AdGroups to be created per
      Campaign.

  Returns:
    a list containing the operations that will add the desired number of
    AdGroups to each of the provided Campaigns.
  """
  adgroup_operations = [
      {
          # The xsi_type of the operation can usually be guessed by the API
          # because a given service only handles one type of operation.
          # However, batch jobs process operations of different types, so
          # the xsi_type must always be explicitly defined for these
          # operations.
          'xsi_type': 'AdGroupOperation',
          'operand': {
              'campaignId': campaign_operation['operand']['id'],
              'id': batch_job_helper.GetId(),
              'name': 'Batch Ad Group #%s' % uuid.uuid4(),
              'biddingStrategyConfiguration': {
                  'bids': [
                      {
                          'xsi_type': 'CpcBid',
                          'bid': {
                              'microAmount': 10000000
                          }
                      }
                  ]
              }
          },
          'operator': 'ADD'
      }
      for campaign_operation in campaign_operations
      for _ in range(number_of_adgroups)]

  return adgroup_operations


def BuildBudgetOperations(batch_job_helper):
  """Builds the operations needed to create a new Budget.

  Note: When the Budget is created, it will have a different Id than the one
  generated here as a temporary Id. This is just used to identify it in the
  BatchJobService.

  Args:
    batch_job_helper: a BatchJobHelper instance.

  Returns:
    a list containing the operation that will create a new Budget.
  """
  # A list of operations creating a Budget.
  budget_operations = [{
      # The xsi_type of the operation can usually be guessed by the API because
      # a given service only handles one type of operation. However, batch jobs
      # process operations of different types, so the xsi_type must always be
      # explicitly defined for these operations.
      'xsi_type': 'BudgetOperation',
      'operand': {
          'name': 'Batch budget #%s' % uuid.uuid4(),
          # This is a temporary Id used by the BatchJobService to identify the
          # Budget for operations that require a budgetId.
          'budgetId': batch_job_helper.GetId(),
          'amount': {
              'microAmount': '50000000'
          },
          'deliveryMethod': 'STANDARD'
      },
      'operator': 'ADD'
  }]

  return budget_operations


def BuildCampaignCriterionOperations(campaign_operations):
  """Builds the operations needed to create Negative Campaign Criterion.

  Args:
    campaign_operations: a list containing the operations that will add
      Campaigns.

  Returns:
    a list containing the operations that will create a new Negative Campaign
    Criterion associated with each provided Campaign.
  """
  criterion_operations = [
      {
          # The xsi_type of the operation can usually be guessed by the API
          # because a given service only handles one type of operation.
          # However, batch jobs process operations of different types, so
          # the xsi_type must always be explicitly defined for these
          # operations.
          'xsi_type': 'CampaignCriterionOperation',
          'operand': {
              'xsi_type': 'NegativeCampaignCriterion',
              'campaignId': campaign_operation['operand']['id'],
              'criterion': {
                  'xsi_type': 'Keyword',
                  'matchType': 'BROAD',
                  'text': 'venus'
              }
          },
          'operator': 'ADD'
      }
      for campaign_operation in campaign_operations]

  return criterion_operations


def BuildCampaignOperations(batch_job_helper,
                            budget_operations, number_of_campaigns=1):
  """Builds the operations needed to create a new Campaign.

  Note: When the Campaigns are created, they will have a different Id than those
  generated here as a temporary Id. This is just used to identify them in the
  BatchJobService.

  Args:
    batch_job_helper: a BatchJobHelper instance.
    budget_operations: a list containing the operation that will add the budget
      used by these Campaigns.
    number_of_campaigns: an int number defining the number of campaigns to be
      created.

  Returns:
    a list containing the operations to create the desired number of Campaigns.
  """
  # Grab the temporary budgetId to associate with the new Campaigns.
  budget_id = budget_operations[0]['operand']['budgetId']

  campaign_operations = [
      {
          # The xsi_type of the operation can usually be guessed by the API
          # because a given service only handles one type of operation.
          # However, batch jobs process operations of different types, so
          # the xsi_type must always be explicitly defined for these
          # operations.
          'xsi_type': 'CampaignOperation',
          'operand': {
              'name': 'Batch Campaign #%s' % uuid.uuid4(),
              # Recommendation: Set the campaign to PAUSED when creating it to
              # stop the ads from immediately serving. Set to ENABLED once
              # you've added targeting and the ads are ready to serve.
              'status': 'PAUSED',
              # This is a temporary Id used by the BatchJobService to identify
              # the Campaigns for operations that require a campaignId.
              'id': batch_job_helper.GetId(),
              'advertisingChannelType': 'SEARCH',
              # Note that only the budgetId is required
              'budget': {
                  'budgetId': budget_id
              },
              'biddingStrategyConfiguration': {
                  'biddingStrategyType': 'MANUAL_CPC'
              }
          },
          'operator': 'ADD'
      }
      for _ in range(number_of_campaigns)]

  return campaign_operations


def GetBatchJob(client, batch_job_id):
  """Retrieves the BatchJob with the given id.

  Args:
    client: an instantiated AdWordsClient used to retrieve the BatchJob.
    batch_job_id: a long identifying the BatchJob to be retrieved.
  Returns:
    The BatchJob associated with the given id.
  """
  batch_job_service = client.GetService('BatchJobService', 'v201705')

  selector = {
      'fields': ['Id', 'Status', 'DownloadUrl'],
      'predicates': [
          {
              'field': 'Id',
              'operator': 'EQUALS',
              'values': [batch_job_id]
          }
      ]
  }

  return batch_job_service.get(selector)['entries'][0]


def GetBatchJobDownloadUrlWhenReady(client, batch_job_id,
                                    max_poll_attempts=MAX_POLL_ATTEMPTS):
  """Retrieves the downloadUrl when the BatchJob is complete.

  Args:
    client: an instantiated AdWordsClient used to poll the BatchJob.
    batch_job_id: a long identifying the BatchJob to be polled.
    max_poll_attempts: an int defining the number of times the the BatchJob will
      be checked to determine whether it has completed.

  Returns:
    A str containing the downloadUrl of the completed BatchJob.

  Raises:
    Exception: If the BatchJob hasn't finished after the maximum poll attempts
      have been made.
  """
  batch_job = GetBatchJob(client, batch_job_id)
  poll_attempt = 0
  while (poll_attempt in range(max_poll_attempts) and
         batch_job['status'] in PENDING_STATUSES):
    sleep_interval = (30 * (2 ** poll_attempt) +
                      (random.randint(0, 10000) / 1000))
    print 'Batch Job not ready, sleeping for %s seconds.' % sleep_interval
    time.sleep(sleep_interval)
    batch_job = GetBatchJob(client, batch_job_id)
    poll_attempt += 1

    if 'downloadUrl' in batch_job:
      url = batch_job['downloadUrl']['url']
      print ('Batch Job with Id "%s", Status "%s", and DownloadUrl "%s" ready.'
             % (batch_job['id'], batch_job['status'], url))
      return url
  raise Exception('Batch Job not finished downloading. Try checking later.')


def PrintResponse(batch_job_helper, response_xml):
  """Prints the BatchJobService response.

  Args:
    batch_job_helper: a BatchJobHelper instance.
    response_xml: a string containing a response from the BatchJobService.
  """
  response = batch_job_helper.ParseResponse(response_xml)

  if 'rval' in response['mutateResponse']:
    for data in response['mutateResponse']['rval']:
      if 'errorList' in data:
        print 'Operation %s - FAILURE:' % data['index']
        print '\terrorType=%s' % data['errorList']['errors']['ApiError.Type']
        print '\ttrigger=%s' % data['errorList']['errors']['trigger']
        print '\terrorString=%s' % data['errorList']['errors']['errorString']
        print '\tfieldPath=%s' % data['errorList']['errors']['fieldPath']
        print '\treason=%s' % data['errorList']['errors']['reason']
      if 'result' in data:
        print 'Operation %s - SUCCESS.' % data['index']


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

Add a trial

#!/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.

"""Creates a trial and waits for it to complete.

See the Campaign Drafts and Experiments guide for more information:
https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments

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
from googleads import adwords


BASE_CAMPAIGN_ID = 'INSERT_BASE_CAMPAIGN_ID_HERE'
DRAFT_ID = 'INSERT_DRAFT_ID_HERE'
MAX_POLL_ATTEMPTS = 6


def main(client, base_campaign_id, draft_id):
  # Initialize appropriate services.
  trial_service = client.GetService('TrialService', version='v201705')
  trial_async_error_service = client.GetService('TrialAsyncErrorService',
                                                version='v201705')

  trial = {
      'draftId': draft_id,
      'baseCampaignId': base_campaign_id,
      'name': 'Test Trial #%d' % uuid.uuid4(),
      'trafficSplitPercent': 50
  }

  trial_operation = {'operator': 'ADD', 'operand': trial}
  trial_id = trial_service.mutate([trial_operation])['value'][0]['id']
  selector = {
      'fields': ['Id', 'Status', 'BaseCampaignId', 'TrialCampaignId'],
      'predicates': [{
          'field': 'Id',
          'operator': 'IN',
          'values': [trial_id]
      }]
  }

  # Since creating a trial is asynchronous, we have to poll it to wait for it to
  # finish.
  poll_attempts = 0
  is_pending = True
  trial = None

  while is_pending and poll_attempts < MAX_POLL_ATTEMPTS:
    trial = trial_service.get(selector)['entries'][0]
    print 'Trial ID %d has status "%s"' % (trial['id'], trial['status'])
    poll_attempts += 1
    is_pending = trial['status'] == 'CREATING'

    if is_pending:
      sleep_seconds = 30 * (2 ** poll_attempts)
      print 'Sleeping for %d seconds.' % sleep_seconds
      time.sleep(sleep_seconds)

  if trial['status'] == 'ACTIVE':
    # The trial creation was successful.
    print 'Trial created with ID %d and trial campaign ID %d' % (
        trial['id'], trial['trialCampaignId'])
  elif trial['status'] == 'CREATION_FAILED':
    # The trial creation failed, and errors can be fetched from the
    # TrialAsyncErrorService.
    selector = {
        'fields': ['TrialId', 'AsyncError'],
        'predicates': [{
            'field': 'TrialId',
            'operator': 'IN',
            'values': [trial['id']]
        }]
    }

    errors = trial_async_error_service.get(selector)['entries']

    if not errors:
      print 'Could not retrieve errors for trial %d' % trial['id']
    else:
      print 'Could not create trial due to the following errors:'
      for error in errors:
        print 'Error: %s' % error['asyncError']
  else:
    # Most likely, the trial is still being created. You can continue polling,
    # but we have limited the number of attempts in the example.
    print ('Timed out waiting to create trial from draft %d with base campaign '
           '%d' % (draft_id, base_campaign_id))


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

  main(adwords_client, BASE_CAMPAIGN_ID, DRAFT_ID)

Get all disapproved ads in an ad group

#!/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 gets all disapproved ads for a given campaign.

To add an ad, run add_ads.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


AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'
PAGE_SIZE = 100


def main(client, ad_group_id):
  # Initialize appropriate service.
  ad_group_ad_service = client.GetService('AdGroupAdService', version='v201705')

  # Construct selector and get all ads for a given ad group.
  offset = 0
  selector = {
      'fields': ['Id', 'PolicySummary'],
      'predicates': [
          {
              'field': 'AdGroupId',
              'operator': 'EQUALS',
              'values': [ad_group_id]
          }
      ],
      'paging': {
          'startIndex': str(offset),
          'numberResults': str(PAGE_SIZE)
      }
  }

  more_pages = True
  disapproved_count = 0

  # Display results.
  while more_pages:
    page = ad_group_ad_service.get(selector)

    if 'entries' in page:
      for ad in page['entries']:
        policy_summary = ad['policySummary']

        if policy_summary['combinedApprovalStatus'] != 'DISAPPROVED':
          continue  # Skip ads that are not disapproved.

        disapproved_count += 1

        print ('Ad with id \'%s\' was disapproved with the following policy '
               'topic entries:' % (ad['ad']['id']))

        for policy_topic_entry in policy_summary['policyTopicEntries']:
          print '  topic ID: %s, topic name: %s' % (
              policy_topic_entry['policyTopicId'],
              policy_topic_entry['policyTopicName'])

    offset += PAGE_SIZE
    selector['paging']['startIndex'] = str(offset)
    more_pages = offset < int(page['totalNumEntries'])

  print '%d disapproved ads were found.' % disapproved_count


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

  main(adwords_client, AD_GROUP_ID)

Get all disapproved ads in an ad group using AWQL

#!/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 gets all disapproved ads for a given campaign with AWQL.

To add an ad, run add_ads.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


AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'
PAGE_SIZE = 100


def main(client, ad_group_id):
  # Initialize appropriate service.
  ad_group_ad_service = client.GetService('AdGroupAdService', version='v201705')

  # Construct query and get all ads for a given campaign.
  query = ('SELECT Id, PolicySummary '
           'WHERE AdGroupId = %s '
           'ORDER BY Id' % ad_group_id)
  more_pages = True
  disapproved_count = 0
  offset = 0

  # Display results.
  while more_pages:
    page = ad_group_ad_service.query(query + ' LIMIT %s, %s' % (
        offset, PAGE_SIZE))

    if 'entries' in page:
      for ad in page['entries']:
        policy_summary = ad['policySummary']

        if policy_summary['combinedApprovalStatus'] != 'DISAPPROVED':
          continue  # Skip ads that are not disapproved.

        disapproved_count += 1

        print ('Ad with id \'%s\' was disapproved with the following policy '
               'topic entries:' % (ad['ad']['id']))

        for policy_topic_entry in policy_summary['policyTopicEntries']:
          print '  topic ID: %s, topic name: %s' % (
              policy_topic_entry['policyTopicId'],
              policy_topic_entry['policyTopicName'])

    offset += PAGE_SIZE
    more_pages = offset < int(page['totalNumEntries'])

  print '%d disapproved ads were found.' % disapproved_count


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

  main(adwords_client, AD_GROUP_ID)

Get all campaigns with a specific label

#!/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 gets all campaigns with a specific label.

To add a label to campaigns, run add_campaign_labels.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 time
from googleads import adwords


LABEL_ID = 'INSERT_LABEL_ID_HERE'
PAGE_SIZE = 100


def main(client, label_id):
  # Initialize appropriate service.
  campaign_service = client.GetService('CampaignService', version='v201705')

  offset = 0
  selector = {
      'fields': ['Id', 'Name', 'Labels'],
      # Labels filtering is performed by ID. You can use CONTAINS_ANY to select
      # campaigns with any of the label IDs, CONTAINS_ALL to select campaigns
      # with all of the label IDs, or CONTAINS_NONE to select campaigns with
      # none of the label IDs.
      'ordering': {
          'field': 'Name',
          'sortOrder': 'ASCENDING'
          },
      'paging': {
          'startIndex': str(offset),
          'numberResults': str(PAGE_SIZE)
      },
      'predicates': {
          'field': 'Labels',
          'operator': 'CONTAINS_ANY',
          'values': [label_id]
      }
  }

  more_pages = True
  while more_pages:
    page = campaign_service.get(selector)

    # Display results.
    if 'entries' in page:
      for campaign in page['entries']:
        print ('Campaign found with Id \'%s\', name \'%s\', and labels: %s'
               % (campaign['id'], campaign['name'], campaign['labels']))
    else:
      print 'No campaigns were found.'

    offset += PAGE_SIZE
    selector['paging']['startIndex'] = str(offset)
    more_pages = offset < int(page['totalNumEntries'])
    time.sleep(1)


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

  main(adwords_client, LABEL_ID)

Graduate a trial

#!/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.

"""Illustrates how to graduate a trial.

See the Campaign Drafts and Experiments guide for more information:
https://developers.google.com/adwords/api/docs/guides/campaign-drafts-experiments

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 uuid
from googleads import adwords


TRIAL_ID = 'INSERT_TRIAL_ID_HERE'


def main(client, trial_id):
  # Initialize appropriate services.
  trial_service = client.GetService('TrialService', version='v201705')
  budget_service = client.GetService('BudgetService', version='v201705')

  # To graduate a trial, you must specify a different budget from the base
  # campaign. The base campaign (in order to have had a trial based on it) must
  # have a non-shared budget, so it cannot be shared with the new independent
  # campaign created by graduation.
  budget = {
      'name': 'Budget #%d' % uuid.uuid4(),
      'amount': {'microAmount': 50000000},
      'deliveryMethod': 'STANDARD'
  }

  budget_operation = {'operator': 'ADD', 'operand': budget}
  # Add budget
  budget_id = budget_service.mutate([budget_operation])['value'][0]['budgetId']

  trial = {
      'id': trial_id,
      'budgetId': budget_id,
      'status': 'GRADUATED'
  }

  trial_operation = {'operator': 'SET', 'operand': trial}

  # Update the trial.
  trial = trial_service.mutate([trial_operation])['value'][0]

  # Graduation is a synchronous operation, so the campaign is already ready. If
  # you promote instead, make sure to see the polling scheme demonstrated in
  # add_trial.py to wait for the asynchronous operation to finish.
  print ('Trial ID %d graduated. Campaign %d was given a new budget ID %d and '
         'is no longer dependent on this trial.' % (
             trial['id'], trial['trialCampaignId'], budget_id))


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

  main(adwords_client, TRIAL_ID)

Set ad parameters

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# 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 text ad with ad parameters.

To get ad groups, run get_ad_groups.py. To get keywords, run add_keywords.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


AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'
CRITERION_ID = 'INSERT_KEYWORD_CRITERION_ID_HERE'


def main(client, ad_group_id, criterion_id):
  # Initialize appropriate service.
  ad_group_ad_service = client.GetService('AdGroupAdService', version='v201705')
  ad_param_service = client.GetService('AdParamService', version='v201705')

  # Construct operations for adding text ad object and add to an ad group.
  operations = [{
      'operator': 'ADD',
      'operand': {
          'xsi_type': 'AdGroupAd',
          'adGroupId': ad_group_id,
          'ad': {
              'xsi_type': 'TextAd',
              'finalUrls': ['http://www.example.com'],
              'displayUrl': 'example.com',
              'description1': 'Low-gravity fun for {param1:cheap}.',
              'description2': 'Only {param2:a few} seats left!',
              'headline': 'Luxury Mars Cruises'
          },
          'status': 'ENABLED'
      }
  }]
  ads = ad_group_ad_service.mutate(operations)['value']

  # Display results.
  for ad in ads:
    print ('Text ad with id \'%s\' was successfully added to an ad group with '
           'id \'%s\'.' % (ad['adGroupId'], ad['ad']['id']))

  # Construct operations for setting ad parameters.
  operations = [
      {
          'operator': 'SET',
          'operand': {
              'adGroupId': ad_group_id,
              'criterionId': criterion_id,
              'insertionText': u'£100',
              'paramIndex': '1'
          }
      },
      {
          'operator': 'SET',
          'operand': {
              'adGroupId': ad_group_id,
              'criterionId': criterion_id,
              'insertionText': '50',
              'paramIndex': '2'
          }
      }
  ]
  ad_params = ad_param_service.mutate(operations)

  # Display results.
  for ad_param in ad_params:
    print ('Ad parameter with text \'%s\' was successfully set for criterion '
           'with id \'%s\' and ad group id \'%s\'.'
           % (ad_param['insertionText'], ad_param['criterionId'],
              ad_param['adGroupId']))


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

  main(adwords_client, AD_GROUP_ID, CRITERION_ID)

Set bid modifier

#!/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 sets a bid modifier for the mobile platform on given campaign.

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


CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE'
BID_MODIFIER = '1.5'


def main(client, campaign_id, bid_modifier):
  # Initialize appropriate service.
  campaign_criterion_service = client.GetService(
      'CampaignCriterionService', version='v201705')

  # Create mobile platform.The ID can be found in the documentation.
  # https://developers.google.com/adwords/api/docs/appendix/platforms
  mobile = {
      'xsi_type': 'Platform',
      'id': '30001'
  }

  # Create campaign criterion with modified bid.
  campaign_criterion = {
      'campaignId': campaign_id,
      'criterion': mobile,
      'bidModifier': bid_modifier
  }

  # Create operations.
  operations = [
      {
          'operator': 'SET',
          'operand': campaign_criterion
      }
  ]

  # Make the mutate request.
  result = campaign_criterion_service.mutate(operations)

  # Display the resulting campaign criteria.
  for campaign_criterion in result['value']:
    print ('Campaign criterion with campaign id \'%s\' and criterion id \'%s\' '
           'was updated with bid modifier \'%s\'.'
           % (campaign_criterion['campaignId'],
              campaign_criterion['criterion']['id'],
              campaign_criterion['bidModifier']))


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

  main(adwords_client, CAMPAIGN_ID, BID_MODIFIER)

Validate text ad

#!/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 shows how to use validateOnly SOAP header.

No objects will be created, but exceptions will still be returned.

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 suds

from googleads import adwords


AD_GROUP_ID = 'INSERT_AD_GROUP_ID_HERE'


def main(client, ad_group_id):
  # Initialize appropriate service with validate only flag enabled.
  client.validate_only = True
  ad_group_ad_service = client.GetService('AdGroupAdService', version='v201705')

  # Construct operations to add an expanded text ad.
  operations = [{
      'operator': 'ADD',
      'operand': {
          'xsi_type': 'AdGroupAd',
          'adGroupId': ad_group_id,
          'ad': {
              'xsi_type': 'ExpandedTextAd',
              'headlinePart1': 'Luxury Cruise to Mars',
              'headlinePart2': 'Visit the Red Planet in style.',
              'description': 'Low-gravity fun for everyone!',
              'finalUrls': ['http://www.example.com']
          }
      }
  }]
  ad_group_ad_service.mutate(operations)
  # No error means the request is valid.

  # Now let's check an invalid ad using a very long line to trigger an error.
  operations = [{
      'operator': 'ADD',
      'operand': {
          'xsi_type': 'AdGroupAd',
          'adGroupId': ad_group_id,
          'ad': {
              'xsi_type': 'ExpandedTextAd',
              'headlinePart1': 'Luxury Cruise to Mars',
              'headlinePart2': 'Visit the Red Planet in style.',
              'description': 'Low-gravity fun for all astronauts in orbit',
              'finalUrls': ['http://www.example.com'],
          }
      }
  }]
  try:
    ad_group_ad_service.mutate(operations)
  except suds.WebFault, e:
    print 'Validation correctly failed with \'%s\'.' % str(e)


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

  main(adwords_client, AD_GROUP_ID)

Send feedback about...

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