(Translated by https://www.hiragana.jp/)
Google Ads Developer Blog: python

In October, 2024, Python 3.8 will reach end-of-life and will no longer be supported by the Python Software Foundation. Once Python 3.8 officially reaches end-of-life status, it will also no longer be supported by the Google Ads client library for Python. That means we will not make updates to the library, or address any issues related to compatibility with Python 3.8, outside of critical security updates.

In October, 2024, Python 3.8 will reach end-of-life and will no longer be supported by the Python Software Foundation. Once Python 3.8 officially reaches end-of-life status, it will also no longer be supported by the Google Ads client library for Python. That means we will not make updates to the library, or address any issues related to compatibility with Python 3.8, outside of critical security updates.

In Q1 2025 we will release a new major version of the library that is incompatible with Python 3.8. This new version will include support for Python 3.13. Users of deprecated, or soon-to-be deprecated versions of Python, are at risk of losing access to the Google Ads API. Please note the below timelines:

  • Python 3.7 users will lose access to the API when v15 is sunset on September 25, 2024
  • Python 3.8 users will lose access to the API when v18 is sunset in Q3 or Q4 2025.

Any library users currently relying on Python 3.7 or 3.8 should upgrade their systems to Python 3.9 or higher as soon as possible.

If you have any questions about this change, please file an issue on the client library repository.

In June 2023, support for Python 3.7 was deprecated in the Google Ads API Client Library for Python. In Q1 2024, a major version of the library will be released that makes it incompatible with Python 3.7. Library changes related to compatibility with Python 3.7 will be limited to critical security or stability patches.
In June 2023, support for Python 3.7 was deprecated in the Google Ads API Client Library for Python. In Q1 2024, a major version of the library will be released that makes it incompatible with Python 3.7. Library changes related to compatibility with Python 3.7 will be limited to critical security or stability patches.

Google Ads API users who depend on Python 3.7 can continue using version 22.1.0 of the library, which includes API v15 support, until v15 of the is sunset in September 2024. All Python users should upgrade to Python 3.8 or higher as soon as possible.

In the future, Python users should expect that the library will become incompatible with unsupported versions of Python as soon as they reach end-of-life status. When Python 3.8 becomes unsupported in October 2024, a major version of the library will be released that is incompatible with Python 3.8. At least two months before a Python version deprecation, we will publish a blog post to help remind users of the change.

The below resources are available to help users plan ahead for future language support removal: If you have any questions about this change, please file an issue on the client library repository on GitHub.

On June 27, 2023, Python 3.7 will reach end-of-life and will no longer be supported by the Python Software Foundation. Once Python 3.7 officially reaches end-of-life status, it will also no longer be supported by the ...
On June 27, 2023, Python 3.7 will reach end-of-life and will no longer be supported by the Python Software Foundation. Once Python 3.7 officially reaches end-of-life status, it will also no longer be supported by the Google Ads client library for Python.

While this will not change the functionality of the client library, any issues or bugs related to the library's compatibility with Python 3.7 will not be addressed, and any documentation related to Python 3.7 will be removed.

We recommend library users upgrade their systems to Python 3.8 or higher as soon as possible.

If you have any questions about this change, please file an issue on the client library repository.

On June 11, 2019 we deprecated support for Python 2 in the AdWords/Google Ad Manager client library for Python. As part of our previously announced plans, in mid-November 2019 we will be deprecating support in the Google Ads client library for Python as well.

When version 4.0.0 of the Google Ads client library for Python is released, we will officially end support for Python 2 and versions of Python 3 prior to 3.6.0.

If you use the Google Ads client library for Python, please take note of the following:
  • If you are already using Python version 3.6.0 or later, you can upgrade to Google Ads client library 4.0.0 and no other action is needed. If not, please do not upgrade to version 4.0.0 until you’ve upgraded to Python version 3.6.0 or later.
  • Version 4.0.0 will continue to support previous API versions such as v1_3 but we won't support client library issues related to Python 2 compatibility. For example, we won't release version 4.0.1 to fix a bug that only exists for Python 2 users.

If you have questions about the Python 3 migration, please submit an issue on the Google Ads client library repository’s Issues page, and for general API support please reach out to us on the Google Ads API forum.


Update (Jun 12): Python client library for Google Ads API v20.0.0 is now available on GitHub.

As the official End of Life date for Python 2 approaches, we will be ending support for Python 2 in both the AdWords/Google Ad Manager and Google Ads Python client libraries in 2019. After deprecation the minimum required Python version for both libraries will be 3.6+.

Deprecation will begin with the AdWords/Google Ad Manager Python client library in May. Here’s a timeline for easy reference:
  • mid-May: version 19.0.0 is released to support Google Ad Manager API v201905. Python 2 users should not upgrade to any major version beyond this.
  • mid-May - late-June: Python 2 deprecation window.
  • Last week in June: version 20.0.0 is released that is incompatible with Python 2.
  • July 1: Support for Python 2-related issues in the library ends.
If you are a user of the AdWords/Google Ad Manager client library, please take note of the following:
  • Google Ad Manager Users:
    • If you’re already using Python 3, no need to take action.
    • If you’re using Python 2 you should remain on version 19.0.0 until you’ve migrated to Python 3.
  • AdWords Users:
    • Please migrate to the new Google Ads API.
    • If you’re using Python 2 you should remain on version 19.0.0 until you’ve migrated to the Google Ads API.
  • All Users:
    • Beginning July 1, 2019 we will discontinue prioritizing work and triaging GitHub Issues related to compatibility with Python 2. Note that we will submit patches to version 19.0.0 if any major bugs arise after this deadline.
The Google Ads API client library will continue to be compatible with Python 2 until the end of 2019. We will post more information about that migration at a later date. In the meantime, Python 2 users should start planning their migration to Python 3 as soon as possible in order to avoid complications.

If you have questions about the Python 3 migration please submit an issue on the respective GitHub repository, and for general API support please reach out to us on the Google Ads API forum or the Google Ad Manager API forum.

Python has tons of cool idioms and features that are often overlooked or underutilized. List comprehensions to cut back on the use of unnecessary loops, decorators to wrap functions with annotations, and generator functions are just some that can be applied to working with the DFP API.

Python has tons of cool idioms and features that are often overlooked or underutilized. List comprehensions to cut back on the use of unnecessary loops, decorators to wrap functions with annotations, and generator functions are just some that can be applied to working with the DFP API.

In this post, we'll tackle one of our most asked questions using decorators: "Why am I running into CONCURRENT_MODIFICATION or QUOTA_EXCEEDED errors, and how do I avoid this?".

Addressing these errors using decorators

CONCURRENT_MODIFICATION and QUOTA_EXCEEDED errors are similar in nature - the requests you’re making are failing, but not necessarily because the data you’re sending over is bad. In the first case, one of the objects you’re trying to modify is being updated elsewhere, but you likely want to try again after pulling down the same set of objects. You could certainly write code that retries your operations in all of your services for each object, but it may get a bit hard to maintain (especially with duplicated code). A much cleaner implementation would be to use a decorator!

The Python wiki has an entry under the decorators section that shows how a generic decorator might work for retrying a call. With a few modifications, we can tailor this to capture the two types of errors that might arise:

  import time
  from functools import wraps

  RESPONSES_TO_RETRY = ['CONCURRENT_MODIFICATION', 'QUOTA_EXCEEDED']

  def retry(tries=4, delay=3, backoff=2):
      ''' Decorator that implements an exponential backoff for retrying on errors.

      Args:
        tries: int number of times to execute the wrapped function before failing
        delay: int time to delay in seconds before the FIRST retry
        backoff: int multiplier to extend the initial delay by for each retry
      '''
      def decorated_function_with_retry(func):
          @wraps(func)
          def function_to_retry(*args, **kwargs):
              local_tries, local_delay = tries, delay
              while local_tries > 1:
                  try:
                      return func(*args, **kwargs)
                  except Exception, e:
                      if [response for response in RESPONSES_TO_RETRY
                          if response in e.fault['faultstring']]:
                        print '%s, Retrying in %d seconds...' % (str(e),
                                                                 local_delay)
                        time.sleep(local_delay)
                        local_tries -= 1
                        local_delay *= backoff
              return func(*args, **kwargs)
          return function_to_retry
      return decorated_function_with_retry

Say you were making a call to update line items - with large networks, it’s not unlikely that someone might be editing the line item at the same time. Since you’d want to pull down the most recent copy of the line item any time the update fails, you would want to abstract out the update method to include the getLineItemsByStatement call, e.g.,

  @retry()
  def fetch_and_update_line_item(statement):
    # call to get the line item in question
    response = line_item_service.getLineItemsByStatement(
        statement.ToStatement())

    updated_line_items = []
    if 'results' in response:
      for line_item in response['results']:
        # Do something with your line items here and add them to
        # updated_line_items.

    line_item_service.updateLineItems(updated_line_items)

This would effectively allow you to, in the event of the update failing due to concurrent modification, pull down and update a new copy of the line item. Using the default constructor will retry 4 times with 3, 6, and 12 second delays in between.

To wrap things up, decorators are incredibly useful constructs in Python and are useful for the DFP API for several reasons:

  • Your application will be less flaky and less affected by intermittent application issues.
  • You’re less likely to run into quota errors.
  • This would prevent overwriting other changes (in the case of retrying failed calls on concurrent modification errors).
  • You could also use something like this to log errors on your end, which could help reveal poor code health or inefficient processes.

Make use of decorators in your code, and you'll soon be sitting pretty.