Skip to main content

Google Ads Reports Helper

A Python ETL driver for Google Ads API v24 data extraction and transformation. Simplifies the process of extracting Google Ads data and converting it to database-ready list of dictionaries with comprehensive optimization features.

PyPI version Issues Last Commit License

Features

  • Google Ads API v24: Latest API version support with full compatibility
  • Pure Python Output: Returns list[dict[str, Any]] - perfect for databases and JSON APIs
  • Serverless Optimized: No pandas dependency, faster cold starts, lower memory usage
  • Modern Python 3.11+: Uses latest type hints and language features (supports 3.11-3.13)
  • Flexible Column Naming: Choose between snake_case or camelCase column conventions
  • Smart Zero Filtering: Robust filtering with automatic column detection
  • Custom Reports: Create custom report configurations with full GAQL support
  • Automatic Retries: Built-in retry logic for API reliability
  • Comprehensive Error Handling: Specific exceptions for different failure types
  • Type Safe: Full type hint support for better IDE experience

Installation

pip install google-ads-reports

Quick Start

1. Set up credentials

Create a secrets/google-ads.yaml file with your Google Ads API credentials:

developer_token: "YOUR_DEVELOPER_TOKEN"
client_id: "YOUR_CLIENT_ID"
client_secret: "YOUR_CLIENT_SECRET"
refresh_token: "YOUR_REFRESH_TOKEN"

References:

2. Basic usage

from datetime import date, timedelta
from google_ads_reports import GAdsReport, GAdsReportModel, load_credentials, get_records_info

# Load credentials
credentials = load_credentials()
client = GAdsReport(credentials)

# Configure report parameters
customer_id = "1234567890"
start_date = date.today() - timedelta(days=7)
end_date = date.today() - timedelta(days=1)

# Extract report data - returns list[dict[str, Any]]
records = client.get_gads_report(
    customer_id=customer_id,
    report_model=GAdsReportModel.keyword_report,
    start_date=start_date,
    end_date=end_date,
    filter_zero_impressions=True,  # Remove rows with zero impressions
    column_naming="snake_case"     # Choose: "snake_case" or "camelCase"
)

# Get dataset information
info = get_records_info(records)
print(f"Shape: {info['shape']}")  # (rows, columns)
print(f"Columns: {info['columns']}")

# Save to CSV or JSON
from google_ads_reports import save_report_to_csv, save_report_to_json
save_report_to_csv(records, "keyword_report.csv")
save_report_to_json(records, "keyword_report.json")

Working with the Data

The library returns list[dict[str, Any]] which is perfect for:

# Database insertion
import sqlite3
conn = sqlite3.connect('reports.db')
for record in records:
    columns = ', '.join(record.keys())
    placeholders = ', '.join(['?' for _ in record])
    values = list(record.values())
    conn.execute(f"INSERT INTO campaigns ({columns}) VALUES ({placeholders})", values)

# JSON APIs
import json
json_data = json.dumps(records)

# Pandas (if needed)
import pandas as pd
df = pd.DataFrame(records)

Column Naming Options

Choose between snake_case (database-friendly) or camelCase (API-consistent):

# Snake case (default) - metrics.impressions → impressions
records_snake = client.get_gads_report(
    customer_id=customer_id,
    report_model=GAdsReportModel.keyword_report,
    start_date=start_date,
    end_date=end_date,
    column_naming="snake_case"  # Default
)

# CamelCase - metrics.impressions → metricsImpressions
records_camel = client.get_gads_report(
    customer_id=customer_id,
    report_model=GAdsReportModel.keyword_report,
    start_date=start_date,
    end_date=end_date,
    column_naming="camelCase"
)

Available Report Models

  • GAdsReportModel.adgroup_ad_report - Ad group ad performance
  • GAdsReportModel.keyword_report - Keyword performance
  • GAdsReportModel.search_terms_report - Search terms analysis
  • GAdsReportModel.conversions_report - Conversion tracking
  • GAdsReportModel.video_report - Video ad performance
  • GAdsReportModel.assetgroup_report - Asset group performance

Custom Reports

Create custom report configurations:

from google_ads_reports import create_custom_report

custom_report = create_custom_report(
    report_name="campaign_performance",
    select=[
        "campaign.name",
        "campaign.status",
        "segments.date",
        "metrics.impressions",
        "metrics.clicks",
        "metrics.cost_micros"
    ],
    from_table="campaign",
    where="metrics.impressions > 100"
)

records = client.get_gads_report(customer_id, custom_report, start_date, end_date)

Data Processing Features

The package automatically processes data for optimal usability:

Smart Zero Filtering

Handles multiple zero representations and automatically detects if impression data is available:

records = client.get_gads_report(
    customer_id=customer_id,
    report_model=report_model,
    start_date=start_date,
    end_date=end_date,
    filter_zero_impressions=True  # Removes: 0, "0", 0.0, "0.0", None
)
# Note: Filtering only applied if 'metrics.impressions' column exists in data

Character Encoding Cleanup

  • ASCII Sanitization: Removes non-ASCII characters for database compatibility
  • Null Byte Removal: Strips problematic null bytes (\x00)
  • Length Limiting: Truncates text to 255 characters
  • Whitespace Normalization: Normalizes whitespace characters

Flexible Column Naming

Choose your preferred column naming convention:

Snake Case (Default - Database Friendly):

  • metrics.impressions → impressions
  • segments.date → date
  • adGroupCriterion.keyword → keyword

CamelCase (API Consistent):

  • metrics.impressions → metricsImpressions
  • segments.date → segmentsDate
  • adGroupCriterion.keyword → adGroupCriterionKeyword

Data Output Format

The library returns list[dict[str, Any]] which provides maximum flexibility:

# Example output structure
records = [
    {
        "campaign_name": "Summer Campaign",
        "impressions": 1000,
        "clicks": 50,
        "cost": 25.50,
        "date": "2025-10-01"
    },
    {
        "campaign_name": "Winter Campaign",
        "impressions": 2000,
        "clicks": 100,
        "cost": 45.75,
        "date": "2025-10-01"
    }
]

# Easy conversion to other formats
import pandas as pd
df = pd.DataFrame(records)  # If you need pandas

import json
json_str = json.dumps(records)  # For APIs

# Direct database insertion
for record in records:
    pass

Error Handling

The package provides specific exception types for different scenarios:

from google_ads_reports import (
    GAdsReport,
    AuthenticationError,
    ValidationError,
    APIError,
    DataProcessingError,
    ConfigurationError
)

try:
    records = client.get_gads_report(customer_id, report_model, start_date, end_date)
except AuthenticationError:
    pass
except ValidationError:
    pass
except DataProcessingError:
    pass

Migration Guide

v2.1.0 — Google Ads API v21 → v24

Library dependency: google-ads>=31.0.0 is now required (previously >=24.0.0).

Video report metric renames (Google Ads API v24 deprecations):

Old field (≤v21) New field (v24)
metrics.video_views metrics.video_trueview_views
metrics.video_view_rate metrics.video_trueview_view_rate

After snake_case transformation:

  • video_views → video_trueview_views
  • video_view_rate → video_trueview_view_rate

Update any downstream tables, dashboards, or queries that reference the old column names.

Examples

Check the examples/ directory for comprehensive usage examples:

  • basic_usage.py - Simple report extraction
  • multiple_reports.py - Batch report processing
  • custom_reports.py - Custom report creation

Configuration

Retry Settings

API calls automatically retry on transient errors with configurable settings:

  • Max attempts: 3 (default)
  • Base delay: 1 second
  • Backoff factor: 2x exponential
  • Max delay: 30 seconds

Logging

Configure logging level:

from google_ads_reports import setup_logging
import logging

setup_logging(level=logging.DEBUG)  # Enable debug logging

Requirements

  • Python 3.11-3.13
  • google-ads >= 31.0.0 (Google Ads API v24 support)
  • PyYAML >= 6.0.0
  • python-dotenv >= 1.0.0
  • tqdm >= 4.65.0

License

MIT License - see LICENSE file for details.

Development

For development installation:

git clone https://github.com/machado000/google-ads-reports
cd google-ads-reports
pip install -e ".[dev]"

Support

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Metadata

Release files for google-ads-reports 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for google-ads-reports 2.1.0
File Size Uploaded
google_ads_reports-2.1.0.tar.gz 31.0 kB

Built distribution (wheel)

Table of built distributions (wheels) for google-ads-reports 2.1.0
File Interpreter ABI Platform
google_ads_reports-2.1.0-py3-none-any.whl Python 3 none any

Total release size: 61.9 kB

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

2 release files

1.3.0

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page