Skip to content

Commit

Permalink
[AIRFLOW-7100] Add GoogleAnalyticsGetAdsLinkOperator (#7781)
Browse files Browse the repository at this point in the history
Co-authored-by: michalslowikowski00 <[email protected]>
  • Loading branch information
michalslowikowski00 and michalslowikowski00 committed Mar 20, 2020
1 parent bfce7e9 commit c8088c2
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 10 deletions.
Expand Up @@ -21,14 +21,18 @@

from airflow import models
from airflow.providers.google.marketing_platform.operators.analytics import (
GoogleAnalyticsListAccountsOperator, GoogleAnalyticsRetrieveAdsLinksListOperator,
GoogleAnalyticsGetAdsLinkOperator, GoogleAnalyticsListAccountsOperator,
GoogleAnalyticsRetrieveAdsLinksListOperator,
)
from airflow.utils import dates

default_args = {"start_date": dates.days_ago(1)}

ACCOUNT_ID = os.environ.get("GA_ACCOUNT_ID", "123456789")
WEB_PROPERTY = os.environ.get("GA_WEB_PROPERTY", "UA-12345678-1")
WEB_PROPERTY = os.environ.get("WEB_PROPERTY_ID", "UA-12345678-1")
WEB_PROPERTY_AD_WORDS_LINK_ID = os.environ.get(
"WEB_PROPERTY_AD_WORDS_LINK_ID", "rQafFTPOQdmkx4U-fxUfhj"
)

default_args = {"start_date": dates.days_ago(1)}

with models.DAG(
"example_google_analytics",
Expand All @@ -39,8 +43,17 @@
list_account = GoogleAnalyticsListAccountsOperator(task_id="list_account")
# [END howto_marketing_platform_list_accounts_operator]

# [START howto_marketing_platform_get_ads_link_operator]
get_ad_words_link = GoogleAnalyticsGetAdsLinkOperator(
web_property_ad_words_link_id=WEB_PROPERTY_AD_WORDS_LINK_ID,
web_property_id=WEB_PROPERTY,
account_id=ACCOUNT_ID,
task_id="get_ad_words_link",
)
# [END howto_marketing_platform_get_ads_link_operator]

# [START howto_marketing_platform_retrieve_ads_links_list_operator]
list_ad_link = GoogleAnalyticsRetrieveAdsLinksListOperator(task_id="list_ad_link",
account_id=ACCOUNT_ID,
web_property_id=WEB_PROPERTY)
list_ad_words_link = GoogleAnalyticsRetrieveAdsLinksListOperator(
task_id="list_ad_link", account_id=ACCOUNT_ID, web_property_id=WEB_PROPERTY
)
# [END howto_marketing_platform_retrieve_ads_links_list_operator]
31 changes: 31 additions & 0 deletions airflow/providers/google/marketing_platform/hooks/analytics.py
Expand Up @@ -74,6 +74,37 @@ def list_accounts(self) -> List[Dict[str, Any]]:
break
return result

def get_ad_words_link(
self, account_id: str, web_property_id: str, web_property_ad_words_link_id: str
) -> Dict[str, Any]:
"""
Returns a web property-Google Ads link to which the user has access.
:param account_id: ID of the account which the given web property belongs to.
:type account_id: string
:param web_property_id: Web property-Google Ads link UA-string.
:type web_property_id: string
:param web_property_ad_words_link_id: to retrieve the Google Ads link for.
:type web_property_ad_words_link_id: string
:returns: web property-Google Ads
:rtype: Dict
"""

self.log.info("Retrieving ad words links...")
ad_words_link = (
self.get_conn() # pylint: disable=no-member
.management()
.webPropertyAdWordsLinks()
.get(
accountId=account_id,
webPropertyId=web_property_id,
webPropertyAdWordsLinkId=web_property_ad_words_link_id,
)
.execute(num_retries=self.num_retries)
)
return ad_words_link

def list_ad_words_links(
self, account_id: str, web_property_id: str
) -> List[Dict[str, Any]]:
Expand Down
59 changes: 59 additions & 0 deletions airflow/providers/google/marketing_platform/operators/analytics.py
Expand Up @@ -70,6 +70,65 @@ def execute(self, context):
return result


class GoogleAnalyticsGetAdsLinkOperator(BaseOperator):
"""
Returns a web property-Google Ads link to which the user has access.
.. seealso::
Check official API docs:
https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtReference/management/webPropertyAdWordsLinks/get
.. seealso::
For more information on how to use this operator, take a look at the guide:
:ref:`howto/operator:GoogleAnalyticsGetAdsLinkOperator`
:param account_id: ID of the account which the given web property belongs to.
:type account_id: str
:param web_property_ad_words_link_id: Web property-Google Ads link ID.
:type web_property_ad_words_link_id: str
:param web_property_id: Web property ID to retrieve the Google Ads link for.
:type web_property_id: str
"""

template_fields = (
"api_version",
"gcp_connection_id",
"account_id",
"web_property_ad_words_link_id",
"web_property_id",
)

@apply_defaults
def __init__(
self,
account_id: str,
web_property_ad_words_link_id: str,
web_property_id: str,
api_version: str = "v3",
gcp_connection_id: str = "google_cloud_default",
*args,
**kwargs
):
super().__init__(*args, **kwargs)

self.account_id = account_id
self.web_property_ad_words_link_id = web_property_ad_words_link_id
self.web_property_id = web_property_id
self.api_version = api_version
self.gcp_connection_id = gcp_connection_id

def execute(self, context):
hook = GoogleAnalyticsHook(
api_version=self.api_version, gcp_connection_id=self.gcp_connection_id
)
result = hook.get_ad_words_link(
account_id=self.account_id,
web_property_id=self.web_property_id,
web_property_ad_words_link_id=self.web_property_ad_words_link_id,
)
return result


class GoogleAnalyticsRetrieveAdsLinksListOperator(BaseOperator):
"""
Lists webProperty-Google Ads links for a given web property
Expand Down
20 changes: 20 additions & 0 deletions docs/howto/operator/gcp/analytics.rst
Expand Up @@ -49,6 +49,26 @@ To list accounts from Analytics you can use the
You can use :ref:`Jinja templating <jinja-templating>` with
:template-fields:`airflow.providers.google.marketing_platform.operators.analytics.GoogleAnalyticsListAccountsOperator`

.. _howto/operator:GoogleAnalyticsGetAdsLinkOperator:

Get Ad Words Link
^^^^^^^^^^^^^^^^^

Returns a web property-Google Ads link to which the user has access.
To list web property-Google Ads link you can use the
:class:`~airflow.providers.google.marketing_platform.operators.analytics.GoogleAnalyticsGetAdsLinkOperator`.

.. exampleinclude:: ../../../../airflow/providers/google/marketing_platform/example_dags/example_analytics.py
:language: python
:dedent: 4
:start-after: [START howto_marketing_platform_get_ads_link_operator]
:end-before: [END howto_marketing_platform_get_ads_link_operator]

You can use :ref:`Jinja templating <jinja-templating>` with
:template-fields:`airflow.providers.google.marketing_platform.operators.analytics.GoogleAnalyticsGetAdsLinkOperator`

.. _howto/operator:GoogleAnalyticsRetrieveAdsLinksListOperator:

List Google Ads Links
^^^^^^^^^^^^^^^^^^^^^

Expand Down
Expand Up @@ -26,7 +26,6 @@


class TestGoogleAnalyticsHook(unittest.TestCase):
NUM_RETRIES = 5

def setUp(self):
with mock.patch(
Expand Down Expand Up @@ -77,6 +76,33 @@ def test_list_accounts_for_multiple_pages(self, get_conn_mock):
list_accounts = self.hook.list_accounts()
self.assertEqual(list_accounts, ["a", "b"])

@mock.patch(
"airflow.providers.google.marketing_platform.hooks."
"analytics.GoogleAnalyticsHook.get_conn"
)
def test_get_ad_words_links_call(self, get_conn_mock):
num_retries = 5
account_id = "holy_hand_grenade"
web_property_id = "UA-123456-1"
web_property_ad_words_link_id = "AAIIRRFFLLOOWW"

self.hook.get_ad_words_link(account_id=account_id,
web_property_id=web_property_id,
web_property_ad_words_link_id=web_property_ad_words_link_id, )

get_conn_mock.return_value\
.management.return_value\
.webPropertyAdWordsLinks.return_value\
.get.return_value\
.execute.assert_called_once_with(num_retries=num_retries)

get_conn_mock.return_value \
.management.return_value \
.webPropertyAdWordsLinks.return_value \
.get.assert_called_once_with(accountId=account_id,
webPropertyId=web_property_id,
webPropertyAdWordsLinkId=web_property_ad_words_link_id,)

@mock.patch(
"airflow.providers.google.marketing_platform.hooks."
"analytics.GoogleAnalyticsHook.get_conn"
Expand Down
Expand Up @@ -19,7 +19,8 @@
from unittest import mock

from airflow.providers.google.marketing_platform.operators.analytics import (
GoogleAnalyticsListAccountsOperator, GoogleAnalyticsRetrieveAdsLinksListOperator,
GoogleAnalyticsGetAdsLinkOperator, GoogleAnalyticsListAccountsOperator,
GoogleAnalyticsRetrieveAdsLinksListOperator,
)

API_VERSION = "api_version"
Expand All @@ -32,7 +33,6 @@ class TestGoogleAnalyticsListAccountsOperator(unittest.TestCase):
"analytics.GoogleAnalyticsHook"
)
def test_execute(self, hook_mock):

op = GoogleAnalyticsListAccountsOperator(
api_version=API_VERSION,
gcp_connection_id=GCP_CONN_ID,
Expand Down Expand Up @@ -68,3 +68,33 @@ def test_execute(self, hook_mock):
hook_mock.return_value.list_ad_words_links.assert_called_once_with(
account_id=account_id, web_property_id=web_property_id
)


class TestGoogleAnalyticsGetAdsLinkOperator(unittest.TestCase):
@mock.patch(
"airflow.providers.google.marketing_platform.operators."
"analytics.GoogleAnalyticsHook"
)
def test_execute(self, hook_mock):
account_id = "the_knight_who_says_ni!"
web_property_id = "42"
web_property_ad_words_link_id = "holy_hand_grenade"

op = GoogleAnalyticsGetAdsLinkOperator(
account_id=account_id,
web_property_id=web_property_id,
web_property_ad_words_link_id=web_property_ad_words_link_id,
api_version=API_VERSION,
gcp_connection_id=GCP_CONN_ID,
task_id="test_task",
)
op.execute(context=None)
hook_mock.assert_called_once()
hook_mock.return_value.get_ad_words_link.assert_called_once()
hook_mock.assert_called_once_with(
gcp_connection_id=GCP_CONN_ID, api_version=API_VERSION
)
hook_mock.return_value.get_ad_words_link.assert_called_once_with(
account_id=account_id, web_property_id=web_property_id,
web_property_ad_words_link_id=web_property_ad_words_link_id,
)

0 comments on commit c8088c2

Please sign in to comment.