Skip to content

Commit bc45fa6

Browse files
authored
Add system test and docs for Facebook Ads operators (#8503)
1 parent ac59735 commit bc45fa6

File tree

15 files changed

+194
-128
lines changed

15 files changed

+194
-128
lines changed

airflow/providers/facebook/ads/hooks/ads.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,27 +74,26 @@ def __init__(
7474
def _get_service(self) -> FacebookAdsApi:
7575
""" Returns Facebook Ads Client using a service account"""
7676
config = self.facebook_ads_config
77-
missings = [_each for _each in self.client_required_fields if _each not in config]
78-
if missings:
79-
message = "{missings} fields are missing".format(missings=missings)
80-
raise AirflowException(message)
8177
return FacebookAdsApi.init(app_id=config["app_id"],
8278
app_secret=config["app_secret"],
8379
access_token=config["access_token"],
8480
account_id=config["account_id"],
8581
api_version=self.api_version)
8682

8783
@cached_property
88-
def facebook_ads_config(self) -> None:
84+
def facebook_ads_config(self) -> Dict:
8985
"""
9086
Gets Facebook ads connection from meta db and sets
9187
facebook_ads_config attribute with returned config file
9288
"""
9389
self.log.info("Fetching fb connection: %s", self.facebook_conn_id)
9490
conn = self.get_connection(self.facebook_conn_id)
95-
if "facebook_ads_client" not in conn.extra_dejson:
96-
raise AirflowException("facebook_ads_client not found")
97-
return conn.extra_dejson["facebook_ads_client"]
91+
config = conn.extra_dejson
92+
missings_keys = self.client_required_fields - config.keys()
93+
if missings_keys:
94+
message = "{missings_keys} fields are missing".format(missings_keys=missings_keys)
95+
raise AirflowException(message)
96+
return config
9897

9998
def bulk_facebook_report(
10099
self,

airflow/providers/google/facebook_ads_to_gcs/example_dags/example_ads.py renamed to airflow/providers/google/cloud/example_dags/example_facebook_ads_to_gcs.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424

2525
from airflow import models
2626
from airflow.providers.google.cloud.operators.bigquery import (
27-
BigQueryCreateEmptyDatasetOperator, BigQueryCreateEmptyTableOperator, BigQueryExecuteQueryOperator,
27+
BigQueryCreateEmptyDatasetOperator, BigQueryCreateEmptyTableOperator, BigQueryDeleteDatasetOperator,
28+
BigQueryExecuteQueryOperator,
2829
)
30+
from airflow.providers.google.cloud.operators.facebook_ads_to_gcs import FacebookAdsReportToGcsOperator
31+
from airflow.providers.google.cloud.operators.gcs import GCSCreateBucketOperator, GCSDeleteBucketOperator
2932
from airflow.providers.google.cloud.operators.gcs_to_bigquery import GCSToBigQueryOperator
30-
from airflow.providers.google.facebook_ads_to_gcs.operators.ads import FacebookAdsReportToGcsOperator
3133
from airflow.utils.dates import days_ago
3234

3335
# [START howto_GCS_env_variables]
@@ -56,13 +58,21 @@
5658
default_args = {"start_date": days_ago(1)}
5759

5860
with models.DAG(
59-
"example_fb_operator",
61+
"example_facebook_ads_to_gcs",
6062
default_args=default_args,
6163
schedule_interval=None, # Override to match your needs
6264
) as dag:
6365

64-
create_dataset = BigQueryCreateEmptyDatasetOperator(task_id="create-dataset",
65-
dataset_id=DATASET_NAME)
66+
create_bucket = GCSCreateBucketOperator(
67+
task_id="create_bucket",
68+
bucket_name=GCS_BUCKET,
69+
project_id=GCP_PROJECT_ID,
70+
)
71+
72+
create_dataset = BigQueryCreateEmptyDatasetOperator(
73+
task_id="create_dataset",
74+
dataset_id=DATASET_NAME,
75+
)
6676

6777
create_table = BigQueryCreateEmptyTableOperator(
6878
task_id="create_table",
@@ -77,7 +87,7 @@
7787
],
7888
)
7989

80-
# [START howto_FB_ADS_to_gcs_operator]
90+
# [START howto_operator_facebook_ads_to_gcs]
8191
run_operator = FacebookAdsReportToGcsOperator(
8292
task_id='run_fetch_data',
8393
start_date=days_ago(2),
@@ -88,23 +98,33 @@
8898
gcp_conn_id=GCS_CONN_ID,
8999
object_name=GCS_OBJ_PATH,
90100
)
91-
# [END howto_FB_ADS_to_gcs_operator]
101+
# [END howto_operator_facebook_ads_to_gcs]
92102

93-
# [START howto_operator_gcs_to_bq]
94103
load_csv = GCSToBigQueryOperator(
95104
task_id='gcs_to_bq_example',
96105
bucket=GCS_BUCKET,
97106
source_objects=[GCS_OBJ_PATH],
98107
destination_project_dataset_table=f"{DATASET_NAME}.{TABLE_NAME}",
99-
write_disposition='WRITE_TRUNCATE')
100-
# [END howto_operator_gcs_to_bq]
108+
write_disposition='WRITE_TRUNCATE'
109+
)
101110

102-
# [START howto_operator_read_data_from_gcs]
103111
read_data_from_gcs_many_chunks = BigQueryExecuteQueryOperator(
104112
task_id="read_data_from_gcs_many_chunks",
105113
sql=f"SELECT COUNT(*) FROM `{GCP_PROJECT_ID}.{DATASET_NAME}.{TABLE_NAME}`",
106114
use_legacy_sql=False,
107115
)
108-
# [END howto_operator_read_data_from_gcs]
109116

110-
create_dataset >> create_table >> run_operator >> load_csv >> read_data_from_gcs_many_chunks
117+
delete_bucket = GCSDeleteBucketOperator(
118+
task_id="delete_bucket",
119+
bucket_name=GCS_BUCKET,
120+
)
121+
122+
delete_dataset = BigQueryDeleteDatasetOperator(
123+
task_id="delete_dataset",
124+
project_id=GCP_PROJECT_ID,
125+
dataset_id=DATASET_NAME,
126+
delete_contents=True,
127+
)
128+
129+
create_bucket >> create_dataset >> create_table >> run_operator >> load_csv
130+
load_csv >> read_data_from_gcs_many_chunks >> delete_bucket >> delete_dataset

airflow/providers/google/facebook_ads_to_gcs/operators/ads.py renamed to airflow/providers/google/cloud/operators/facebook_ads_to_gcs.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class FacebookAdsReportToGcsOperator(BaseOperator):
4242
For more information on the Facebook Ads Python SDK, take a look at the docs:
4343
https://github.com/facebook/facebook-python-business-sdk
4444
45+
.. seealso::
46+
For more information on how to use this operator, take a look at the guide:
47+
:ref:`howto/operator:FacebookAdsReportToGcsOperator`
48+
4549
:param bucket: The GCS bucket to upload to
4650
:type bucket: str
4751
:param obj: GCS path to save the object. Must be the full file path (ex. `path/to/file.txt`)

airflow/providers/google/facebook_ads_to_gcs/__init__.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

airflow/providers/google/facebook_ads_to_gcs/example_dags/__init__.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

airflow/providers/google/facebook_ads_to_gcs/operators/__init__.py

Lines changed: 0 additions & 16 deletions
This file was deleted.

airflow/utils/db.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,12 @@ def create_default_connections(session=None):
245245
Connection(
246246
conn_id="facebook_default",
247247
conn_type="facebook_social",
248-
schema="""
249-
{
250-
"facebook_ads_client": {
251-
"account_id": "act_123456789",
252-
"app_id": "1234567890",
253-
"app_secret": "1f45tghxxxx12345",
254-
"access_token": "ABcdEfghiJKlmnoxxyz"
248+
extra="""
249+
{ "account_id": "<AD_ACCOUNNT_ID>",
250+
"app_id": "<FACEBOOK_APP_ID>",
251+
"app_secret": "<FACEBOOK_APP_SECRET>",
252+
"access_token": "<FACEBOOK_AD_ACCESS_TOKEN>"
255253
}
256-
}
257254
""",
258255
),
259256
session

docs/autoapi_templates/index.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ All operators are in the following packages:
110110

111111
airflow/providers/exasol/operators/index
112112

113-
airflow/providers/google/facebook_ads_to_gcs/operators/index
114-
115113
airflow/providers/ftp/sensors/index
116114

117115
airflow/providers/google/ads/operators/index
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
.. Licensed to the Apache Software Foundation (ASF) under one
2+
or more contributor license agreements. See the NOTICE file
3+
distributed with this work for additional information
4+
regarding copyright ownership. The ASF licenses this file
5+
to you under the Apache License, Version 2.0 (the
6+
"License"); you may not use this file except in compliance
7+
with the License. You may obtain a copy of the License at
8+
9+
.. http://www.apache.org/licenses/LICENSE-2.0
10+
11+
.. Unless required by applicable law or agreed to in writing,
12+
software distributed under the License is distributed on an
13+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
KIND, either express or implied. See the License for the
15+
specific language governing permissions and limitations
16+
under the License.
17+
18+
19+
20+
Facebook Ads To GCS Operators
21+
==============================
22+
23+
.. contents::
24+
:depth: 1
25+
:local:
26+
27+
Prerequisite Tasks
28+
^^^^^^^^^^^^^^^^^^
29+
30+
.. include:: _partials/prerequisite_tasks.rst
31+
32+
.. _howto/operator:FacebookAdsReportToGcsOperator:
33+
34+
FacebookAdsReportToGcsOperator
35+
------------------------------
36+
37+
Use the
38+
:class:`~airflow.providers.google.cloud.operators.facebook_ads_to_gcs.FacebookAdsReportToGcsOperator`
39+
to execute a Facebook ads report fetch and load to GCS.
40+
41+
.. exampleinclude:: ../../../../airflow/providers/google/cloud/example_dags/example_facebook_ads_to_gcs.py
42+
:language: python
43+
:start-after: [START howto_operator_facebook_ads_to_gcs]
44+
:end-before: [END howto_operator_facebook_ads_to_gcs]
45+
46+
Reference
47+
^^^^^^^^^
48+
49+
For further information, look at:
50+
51+
* `Client Library Documentation <https://github.com/facebook/facebook-python-business-sdk>`__
52+
* `Product Documentation <https://developers.facebook.com/docs/business-manager-api/>`__

docs/operators-and-hooks-ref.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -806,8 +806,8 @@ These integrations allow you to copy data from/to Google Cloud Platform.
806806

807807
* - `Facebook Ads <http://business.facebook.com>`__
808808
- `Google Cloud Storage (GCS) <https://cloud.google.com/gcs/>`__
809-
-
810-
- :mod:`airflow.providers.google.facebook_ads_to_gcs.operators.ads`
809+
- :doc:`How to use <howto/operator/gcp/facebook_ads_to_gcs>`
810+
- :mod:`airflow.providers.google.cloud.operators.facebook_ads_to_gcs`
811811

812812
* - `Google BigQuery <https://cloud.google.com/bigquery/>`__
813813
- `MySQL <https://www.mysql.com/>`__

0 commit comments

Comments
 (0)