# google-ads and the shape of a generated ads API client

> The google-ads Python package is a generated client for the Google Ads API, distributed on PyPI, versioned in lockstep with the API, and organised around a set of service clients plus a YAML configuration file. It suits teams automating ad account work from Python, and it is a poor fit for anyone who wants a light wrapper over a couple of reporting calls.

**googleads/google-ads-python** — Google Ads API Client Library for Python

- Repository: https://github.com/googleads/google-ads-python
- Stars: 760 · Forks: 548
- Language: Python
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/googleads-google-ads-python

## A generated client, which is why the version number tracks the API

The google-ads package is the Python client library for the Google Ads API, hosted by Google and published on PyPI. The project description in the package manifest is minimal, "Client library for the Google Ads API", and the version in pyproject.toml is 34.0.0.

The version number is the first thing to notice, because it is not the library's own release scheme. It moves in step with the API it talks to, which means a major bump in the package is a signal that the service surface changed, not that the library was refactored. The recent history shows the pace: 32.0.0 on 2026-09-09, 33.0.0 on 2026-09-23 and 34.0.0 on 2026-10-15.

That design follows from how the client is produced. The library is generated rather than hand written, which is the only way a client can cover the full surface of an ads API with campaigns, ad groups, ads, criteria, bidding strategies, resources and reporting queries without an army of maintainers. The consequence for you is that the library mirrors the API closely, so you will find yourself reading the API reference and the library docs side by side, and the field names in your code will look like the API field names. That is a feature when you are porting logic from another language's client, and a mild adjustment when you are used to a library that renames things.

The repository is not archived and the last push was on 2026-10-22, so the current major version is the one being worked on.

## Credentials live in a YAML file that the client reads at run time

The configuration model is the part of this library you have to get right before anything else works, and the repository shows it plainly: there is a `google-ads.yaml` file at the top level.

The features the documentation lists are terse but they are the real selling points: distributed via PyPI, easy management of credentials, and easy creation of Google Ads API service clients. That middle item is what the YAML file is for. A single configuration file describes the client ID, the client secret, the refresh token and the developer token, and the same file can hold several named configurations so one codebase can talk to different accounts.

The dependency list in pyproject.toml explains what handles the credentials. `google-auth-oauthlib` is required, with the constraint `>= 1.0.0, < 2.0.0`, and that is the OAuth layer doing the token exchange and refresh. Alongside it sit `google-api-core`, `googleapis-common-protos` and the gRPC packages, and the gRPC packages are installed together with the rest rather than being an optional extra.

The version constraints are more interesting than they look. `google-api-core` is required at `>= 2.13.0, <= 3.0.0`, but on Python 3.13 and above the floor moves to `>= 2.22.0`. `googleapis-common-protos` follows the same pattern, `>= 1.56.3, < 2.0.0` generally and `>= 1.63.2, < 2.0.0` on Python 3.13 and above. So the library carries two dependency sets and selects between them by interpreter version, which is what you would expect from a client that has to keep working across a range of Python releases.

## Installing is one pip command, but the versions are the decision

The installation instruction in the project documentation is a single line:

```bash
  pip install google-ads
```

The requirement stated above it is Python 3.9 or later, and the packaging metadata is more precise: `requires-python = ">=3.9, <3.15"`. The classifiers list Python 3.9 through 3.14 individually, and the pinned dependency ranges in pyproject.toml are consistent with that spread.

So the version of Python is not a detail to sort out later. There is a lower bound, an upper bound, and a two-tier dependency set that switches on Python 3.13. If your environment runs on 3.15 or newer, the package will not install at all, and if it runs on 3.8 the requirement is not met either. Pinning the interpreter and pinning the library are the same task.

The build system is plain setuptools. The pyproject.toml declares `requires = ["setuptools"]` and the `setuptools.build_meta` backend, with the licence read from a `LICENSE` file and the readme from `./README.rst`. That last detail explains the file naming in the repository: the readme is reStructuredText rather than Markdown, which is why the documentation in the repository is in rst syntax with the section underlines and the link targets at the bottom.

The distribution channel is PyPI, so the usual `pip install` path is the supported one and there is no separate vendor package to configure. The package is named `google-ads` with a hyphen, and the import name uses an underscore, so the difference between the two is worth keeping straight in a requirements file.

## The examples directory is the closest thing to documentation in the repo

The documentation proper lives on the developer site, and the project says so plainly, pointing readers to the Developer Site for how to install, configure and use the library. The repository's own documentation is a reStructuredText readme with a features list, a requirements line, the install command, and links to the issue tracker, the API documentation and API support.

What the repository does carry is a large body of example code, and it is organised by task rather than by API object. There are 23 directories under `examples/`, and the names tell you what the library is used for: account_management, advanced_operations, assets, asyncio, audience_insights, authentication, basic_operations, billing, campaign_management, custom_logging_interceptor, error_handling, experiments, google-ads-account-analyzer-demo, incentives, misc, planning, recommendations, remarketing, reporting, shopping_ads, targeting, travel and utils.

Several of those directories answer questions the readme does not. `authentication/` covers how to get a client at all, `asyncio/` covers the asynchronous path, `error_handling/` covers what happens when the API rejects a request, and `custom_logging_interceptor/` covers hooking your own logging into the transport. `reporting/` is the one an analytics team will read first, and `google-ads-account-analyzer-demo/` shows a complete application rather than a snippet.

For a library this size, the examples are the practical specification. A reader who wants to know how paging works, how a query stream is consumed, or how to retry, will find the answer in one of these directories rather than in the readme.

## The Docker and nox setup tests six Python versions at once

The repository is set up for continuous testing across the whole supported interpreter range, and the two files that do it are worth reading because they describe what the maintainers consider the supported surface.

The Dockerfile starts from `ubuntu:24.04` and installs six Python versions in one image:

```dockerfile
ARG PYTHON_VERSIONS="3.14 3.13 3.12 3.11 3.10 3.9"
```

It copies the `uv` binary from the Astral registry image, uses `uv python install` to place those interpreters, installs `nox[uv]` as a tool, and sets `NOX_DEFAULT_VENV_BACKEND=uv` so nox creates its environments with uv rather than the default backend. The environment also pins `TZ=Etc/GMT` and puts `/root/.local/bin` on the path. The base packages installed are `ca-certificates`, `curl`, `gnupg2`, `git` and `openssh-client`, which is the set you need for fetching dependencies over TLS and verifying signatures.

The `noxfile.py` at the root is the session definition, and nox is the reason the Dockerfile exists in this shape: one image, many interpreter versions, and a session matrix that runs against all of them.

The practical value for an adopter is indirect but real. It tells you that the 3.9 to 3.14 range is not aspirational, it is what gets tested on every change, and it tells you that the two-tier dependency pinning you noticed earlier is deliberate enough to be expressed in the package metadata rather than left to chance. The cost is that the same care has to be applied on your side, which is why the interpreter version question earlier is not a nitpick.

## What you give up by not using the library, and what it costs to use it

The alternative is to call the Google Ads API directly over HTTP with your own OAuth client, and for a single request that is often the better decision.

The trade is size against convenience. A direct call means one HTTP request, one token refresh, and a JSON response you parse yourself. It has no dependency, no generated surface area, and nothing to upgrade. For a script that lists campaigns once a week, that is the whole design.

The library earns its place when the work touches the awkward parts of the API. A reporting query over large result sets returns a page at a time, and the library handles the paging and the request batching. Enum-heavy fields arrive as generated wrapper classes rather than raw strings, so an invalid enum value fails in your code with a readable name instead of at the far end of a request. Resource names, which the API uses as identifiers throughout, get consistent handling. And a long script touching a dozen different services does not need a dozen different service clients written from scratch, because the library ships them all.

The costs are real and worth pricing. The dependency tree is large, and it includes the gRPC stack whether or not you use gRPC. The generated surface means you are tied to a major version, and because versions track the API, a pin you choose today may be behind what your account's API version supports, or ahead of what your other systems expect. On top of that, an upgrade from one major to the next can rename or reshape fields, so a routine dependency bump is a code review event.

So the decision rule is simple. A few calls, once in a while: use the API directly. A pipeline that reports on accounts, analyses performance or applies changes at volume: the library is worth the dependency.

## Conclusion

The google-ads package fits a team that already lives in the Google Ads API and wants Python for account analysis, bulk operations or reporting pipelines, and that accepts a dependency on a service whose surface changes with every major version. It is the wrong choice for a single API call, where the HTTP API and an OAuth client would do, and for anyone who cannot accept that a library upgrade can break their code. Before adopting, verify three things: which Python version your environment pins, since the package requires `>=3.9, <3.15` and lists classifiers through 3.14, what the `google-ads.yaml` configuration expects on your machine, and whether the major version you pin matches the API version your account is on. The code is Apache-2.0, the last push was on 2026-10-22, and releases 32.0.0, 33.0.0 and 34.0.0 landed within five weeks.

## FAQ

### How do I install the Google Ads API client library for Python?

Run `pip install google-ads`. The package is distributed via PyPI, and the metadata requires Python `>=3.9, <3.15`, with classifiers listed for Python 3.9 through 3.14.

### Which Python versions does google-ads support?

The requirement is Python 3.9 or higher with an upper bound of 3.15, and the classifiers list 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14. The dependency pins differ on Python 3.13 and above, where google-api-core moves to `>= 2.22.0` and googleapis-common-protos to `>= 1.63.2`.

### How does the google-ads library handle credentials?

Credentials are managed through a `google-ads.yaml` configuration file at the top level of the repository, and OAuth handling is provided by the `google-auth-oauthlib` dependency, constrained to `>= 1.0.0, < 2.0.0`. The documented features call out easy management of credentials and easy creation of API service clients.

### What is the current version of the google-ads Python library?

The version in the package metadata is 34.0.0, released on 2026-10-15. Before that came 33.0.0 on 2026-09-23 and 32.0.0 on 2026-09-09, so the major version moves in step with the API.

### Where can I find example code for the google-ads library?

The `examples/` directory in the repository is organised by task, with folders such as authentication, asyncio, error_handling, reporting, targeting, campaign_management and billing. Full usage documentation is on the developer site the project points to.

## Sources

- [googleads/google-ads-python on GitHub](https://github.com/googleads/google-ads-python)
- [Issues](https://github.com/googleads/google-ads-python/issues)
- [License: Apache-2.0](https://github.com/googleads/google-ads-python/blob/main/LICENSE)
- [README](https://github.com/googleads/google-ads-python/blob/main/README.md)
- [Releases](https://github.com/googleads/google-ads-python/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/googleads-google-ads-python
