Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ and writes it virtually anywhere.
* [Google Merchant Center](https://google.github.io/garf/fetchers/merchant-center-api/)
* [Bid Manager](https://google.github.io/garf/fetchers/bid-manager/)
* [Google Ads](https://google.github.io/garf/fetchers/google-ads/)
* [Search Ads 360](https://google.github.io/garf/fetchers/google-ads/#search-ads-360)
* [REST](fetchers/rest.md)


Expand Down
71 changes: 68 additions & 3 deletions docs/fetchers/google-ads.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
## garf for Google Ads API
## garf for Google Ads & Search Ads 360 API

[![PyPI](https://img.shields.io/pypi/v/garf-google-ads?logo=pypi&logoColor=white&style=flat-square)](https://pypi.org/project/garf-google-ads)
[![Downloads PyPI](https://img.shields.io/pypi/dw/garf-google-ads?logo=pypi)](https://pypi.org/project/garf-google-ads/)

Interacts with [Google Ads API](https://developers.google.com/google-ads-api).
Interacts with [Google Ads API](https://developers.google.com/google-ads-api) and [Search Ads 360 API](https://developers.google.com/search-ads/reporting).

## Install

Expand All @@ -21,11 +21,12 @@ uv pip install garf-executors garf-google-ads
```
///

## Usage
## Google Ads

### Prerequisites

* [Google Ads API](https://console.cloud.google.com/apis/library/googleads.googleapis.com) enabled.
* `google-ads.yaml` file

/// tab | cli
```bash
Expand Down Expand Up @@ -78,3 +79,67 @@ console_writer.write(fetched_report, 'query')
| `expand-mcc` | Whether to force account expansion if MCC is provided | `False` by default |
| `customer-ids-query` | Optional query to find account satisfying specific condition | |
| `version` | Version of Google Ads API | |

## Search Ads 360

!!!note
Install extra dependency to work with Search Ads 360 API
```
pip install garf-google-ads[search-ads-360]
```

### Prerequisites

* [Search Ads 360 API](https://console.cloud.google.com/apis/library/doubleclicksearch.googleapis.com) enabled.
* `search-ads-360.yaml` file.

/// tab | cli
```bash
echo """
SELECT
campaign.id,
metrics.clicks AS clicks
FROM campaign
WHERE segments.date DURING LAST_7_DAYS
" > query.sql
garf query.sql --source search-ads-360 \
--output console
```
///

/// tab | python

```python
import os

from garf.io import writer
from garf.community.google.ads import SearchAds360ApiReportFetcher

query = """
SELECT
campaign.id,
metrics.clicks AS clicks
FROM campaign
WHERE segments.date DURING LAST_7_DAYS
"""

fetched_report = (
SearchAds360ApiReportFetcher(
path_to_config=os.getenv('SEARCH_ADS_360_CONFIGURATION_FILE_PATH')
)
.fetch(query, account=os.getenv('SEARCH_ADS_360_ACCOUNT'))
)

console_writer = writer.create_writer('console')
console_writer.write(fetched_report, 'query')
```
///

### Available source parameters

| name | values| comments |
|----- | ----- | -------- |
| `account` | Account(s) to get data from | Can be MCC(s) as well |
| `path-to-config` | Path to `search-ads-360.yaml` file | `~/search-ads-360.yaml` is a default location |
| `expand-mcc` | Whether to force account expansion if MCC is provided | `False` by default |
| `customer-ids-query` | Optional query to find account satisfying specific condition | |
1 change: 1 addition & 0 deletions docs/fetchers/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
* [Google Merchant Center](merchant-center-api.md)
* [Bid Manager](bid-manager.md)
* [Google Ads](google-ads.md)
* [Search Ads 360](google-ads.md#search-ads-360)
7 changes: 4 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ and write it virtually anywhere.
## Supported APIs

* [YouTube Data API](fetchers/youtube.md#youtube-data-api)
* [YouTube Analytics API](fetchers/yotube.md#youtube-analytics-api)
* [YouTube Analytics API](fetchers/youtube.md#youtube-analytics-api)
* [Google Analytics](fetchers/google-analytics-api.md)
* [Google Merchant Center](fetchers/merchant-center-api.md)
* [Google Merchant Center](fetchers/bid-manager.md)
* [Bid Manager](fetchers/bid-manager.md)
* [Google Ads](fetchers/google-ads.md)
* [Search Ads 360](fetchers/google-ads.md#search-ads-360)
* [REST](fetchers/rest.md)

## Installation
Expand All @@ -37,7 +38,7 @@ pip install garf-executors

/// tab | uv
```bash
uv add garf-executors
uv pip install garf-executors
```
///

Expand Down
7 changes: 3 additions & 4 deletions docs/usage/api-executor.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ pip install garf-executors
```
## Run

Let's take an example of working with [YouTube Data API fetcher](../fetchers/youtube-data-api.md) to get some stats on YouTube video.

Let's take an example of working with [YouTube Data API fetcher](../fetchers/youtube.md#youtube-data-api) to get some stats on YouTube video.
!!! important
Make sure that corresponding library for interacting with YouTube Data API is installed

```bash
pip install garf_youtube_data_api
pip install garf-youtube
```

/// tab | bash
Expand Down Expand Up @@ -104,7 +103,7 @@ Cache has `cache_ttl_seconds` parameter (default is 3600 seconds or 1 hour).
/// tab | bash

```
garf query.sql --source youtube_data_api \
garf query.sql --source youtube-data-api \
--output console \
--source.id=VIDEO_ID \
--enable-cache \
Expand Down
12 changes: 10 additions & 2 deletions libs/community/google/ads/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
# `garf` for Google Ads API
# `garf` for Google Ads & Search Ads 360 API

[![PyPI](https://img.shields.io/pypi/v/garf-google-ads?logo=pypi&logoColor=white&style=flat-square)](https://pypi.org/project/garf-google-ads)
[![Downloads PyPI](https://img.shields.io/pypi/dw/garf-google-ads?logo=pypi)](https://pypi.org/project/garf-google-ads/)

`garf-google-ads` simplifies fetching data from Google Ads API using SQL-like queries.
`garf-google-ads` simplifies fetching data from Google Ads & Search Ads 360 API using SQL-like queries.

## Prerequisites

* [Google Ads API](https://console.cloud.google.com/apis/library/googleads.googleapis.com) enabled.
* (Optional) [Search Ads 360 API](https://console.cloud.google.com/apis/library/doubleclicksearch.googleapis.com) enabled if you want to interact with Search Ads 360 API.


## Installation

`pip install garf-google-ads`

> To work with Search Ads 360 API install run `pip install garf-google-ads[search-ads-360]`

## Usage

### Run as a library
Expand Down Expand Up @@ -67,3 +71,7 @@ where:
| `expand-mcc` | Whether to force account expansion if MCC is provided | `False` by default |
| `customer-ids-query` | Optional query to find account satisfying specific condition | |
| `version` | Version of Google Ads API | |

## Documentation

You can find a documentation on `garf-google-ads` [here](https://google.github.io/garf/fetchers/google-ads/).
16 changes: 12 additions & 4 deletions libs/community/google/ads/garf/community/google/ads/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Library for getting reports from Google Ads API."""
"""Library for getting reports from Google Ads & Search Ads 360 API."""

from garf.community.google.ads.api_clients import GoogleAdsApiClient
from garf.community.google.ads.report_fetcher import GoogleAdsApiReportFetcher
from garf.community.google.ads.api_clients import (
GoogleAdsApiClient,
SearchAds360ApiClient,
)
from garf.community.google.ads.report_fetcher import (
GoogleAdsApiReportFetcher,
SearchAds360ApiReportFetcher,
)

__all__ = [
'GoogleAdsApiClient',
'GoogleAdsApiReportFetcher',
'SearchAds360ApiClient',
'SearchAds360ApiReportFetcher',
]

__version__ = '1.0.2'
__version__ = '1.1.0'
47 changes: 47 additions & 0 deletions libs/community/google/ads/garf/community/google/ads/api_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,53 @@ class GoogleAdsApiClientError(exceptions.GoogleAdsApiError):
"""Google Ads API client specific error."""


class SearchAds360ApiClient(api_clients.BaseClient):
"""Client to interact Search Ads 360 API.

Attributes:
default_config: Default location for search-ads-360.yaml file.
client: GoogleAdsClient to perform stream and mutate operations.
search_ads_360_service: Service to perform stream operations.
"""

default_config = str(Path.home() / 'search-ads-360.yaml')

def __init__(
self,
path_to_config: str | os.PathLike[str] = os.getenv(
'SEARCH_ADS_360_CONFIGURATION_FILE_PATH', default_config
),
**kwargs: str,
) -> None:
"""Initializes SearchAds360ApiClient based on a config file.

Args:
path_to_config: Path to search-ads-360.yaml file.
"""
from garf.community.google.ads import search_ads_360_client

self.client = search_ads_360_client.SearchAds360Client.load_from_file(
path_to_config
)
self.search_ads_360_service = self.client.get_service()
self.kwargs = kwargs

def get_response(
self, request, account: int, **kwargs: str
) -> api_clients.GarfApiResponse:
from garf.community.google.ads import search_ads_360_client

request = search_ads_360_client.SearchSearchAds360StreamRequest(
query=request.text, customer_id=account
)
response = self.search_ads_360_service.search_stream(request)
results = [result for batch in response for result in batch.results]
return api_clients.GarfApiResponse(
results=results,
results_placeholder=[search_ads_360_client.SearchAds360Row()],
)


class GoogleAdsApiClient(api_clients.BaseClient):
"""Client to interact with Google Ads API.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import garf.core
from garf.community.google.ads import (
GoogleAdsApiClient,
api_clients,
builtins,
exceptions,
parsers,
Expand All @@ -34,11 +34,13 @@ class GoogleAdsApiReportFetcherError(exceptions.GoogleAdsApiError):


class GoogleAdsApiReportFetcher(garf.core.ApiReportFetcher):
"""Defines report fetcher."""
"""Defines report fetcher for Google Ads API."""

alias = 'google-ads'

def __init__(
self,
api_client: GoogleAdsApiClient | None = None,
api_client: api_clients.GoogleAdsApiClient | None = None,
parser: garf.core.parsers.ProtoParser = parsers.GoogleAdsRowParser,
query_spec: query_editor.GoogleAdsApiQuery = (
query_editor.GoogleAdsApiQuery
Expand All @@ -49,7 +51,7 @@ def __init__(
) -> None:
"""Initializes GoogleAdsApiReportFetcher."""
if not api_client:
api_client = GoogleAdsApiClient(**kwargs)
api_client = api_clients.GoogleAdsApiClient(**kwargs)
self.parallel_threshold = parallel_threshold
super().__init__(
api_client=api_client,
Expand Down Expand Up @@ -206,3 +208,22 @@ def _get_customer_ids(
if customer_id != 0
}
)


class SearchAds360ApiReportFetcher(GoogleAdsApiReportFetcher):
"""Defines report fetcher for Search Ads 360 API."""

alias = 'search-ads-360'

def __init__(
self,
api_client: api_clients.SearchAds360ApiClient | None = None,
**kwargs: str,
) -> None:
"""Initializes SearchAds360ApiReportFetcher."""
if not api_client:
api_client = api_clients.SearchAds360ApiClient(**kwargs)
super().__init__(
api_client=api_client,
**kwargs,
)
Loading