Skip to content

Commit 00a045f

Browse files
anuunchinpjatx
andauthored
Remove default breakdowns and action_breakdowns from Facebook Ads insights source - #644 (#670)
* Remove default breakdowns and action_breakdowns from Facebook Ads insights source * Minor refactors * Import fixes * uv.lock updated --------- Co-authored-by: Philip Johnson <[email protected]>
1 parent 78525b5 commit 00a045f

File tree

6 files changed

+3419
-2988
lines changed

6 files changed

+3419
-2988
lines changed

sources/facebook_ads/__init__.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
)
4040
from .settings import (
4141
FACEBOOK_INSIGHTS_RETENTION_PERIOD,
42-
ALL_ACTION_BREAKDOWNS,
4342
ALL_ACTION_ATTRIBUTION_WINDOWS,
4443
DEFAULT_INSIGHT_FIELDS,
4544
INSIGHT_FIELDS_TYPES,
@@ -126,8 +125,8 @@ def facebook_insights_source(
126125
fields: Sequence[str] = DEFAULT_INSIGHT_FIELDS,
127126
attribution_window_days_lag: int = 7,
128127
time_increment_days: int = 1,
129-
breakdowns: TInsightsBreakdownOptions = "ads_insights",
130-
action_breakdowns: Sequence[str] = ALL_ACTION_BREAKDOWNS,
128+
breakdowns: TInsightsBreakdownOptions = None,
129+
action_breakdowns: Sequence[str] = None,
131130
level: TInsightsLevels = "ad",
132131
action_attribution_windows: Sequence[str] = ALL_ACTION_ATTRIBUTION_WINDOWS,
133132
batch_size: int = 50,
@@ -149,8 +148,8 @@ def facebook_insights_source(
149148
fields (Sequence[str], optional): A list of fields to include in each reports. Note that `breakdowns` option adds fields automatically. Defaults to DEFAULT_INSIGHT_FIELDS.
150149
attribution_window_days_lag (int, optional): Attribution window in days. The reports in attribution window are refreshed on each run.. Defaults to 7.
151150
time_increment_days (int, optional): The report aggregation window in days. use 7 for weekly aggregation. Defaults to 1.
152-
breakdowns (TInsightsBreakdownOptions, optional): A presents with common aggregations. See settings.py for details. Defaults to "ads_insights_age_and_gender".
153-
action_breakdowns (Sequence[str], optional): Action aggregation types. See settings.py for details. Defaults to ALL_ACTION_BREAKDOWNS.
151+
breakdowns (TInsightsBreakdownOptions, optional): A presents with common aggregations. See settings.py for details. Defaults to None (no breakdowns).
152+
action_breakdowns (Sequence[str], optional): Action aggregation types. See settings.py for details. Defaults to None (no action breakdowns).
154153
level (TInsightsLevels, optional): The granularity level. Defaults to "ad".
155154
action_attribution_windows (Sequence[str], optional): Attribution windows for actions. Defaults to ALL_ACTION_ATTRIBUTION_WINDOWS.
156155
batch_size (int, optional): Page size when reading data from particular report. Defaults to 50.
@@ -186,16 +185,7 @@ def facebook_insights(
186185
while start_date <= end_date:
187186
query = {
188187
"level": level,
189-
"action_breakdowns": list(action_breakdowns),
190-
"breakdowns": list(
191-
INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["breakdowns"]
192-
),
193188
"limit": batch_size,
194-
"fields": list(
195-
set(fields)
196-
.union(INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["fields"])
197-
.difference(INVALID_INSIGHTS_FIELDS)
198-
),
199189
"time_increment": time_increment_days,
200190
"action_attribution_windows": list(action_attribution_windows),
201191
"time_ranges": [
@@ -207,6 +197,22 @@ def facebook_insights(
207197
}
208198
],
209199
}
200+
201+
fields_to_use = set(fields)
202+
# Only add breakdowns if explicitly provided
203+
if breakdowns is not None:
204+
query["breakdowns"] = list(
205+
INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["breakdowns"]
206+
)
207+
fields_to_use = fields_to_use.union(
208+
INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["fields"]
209+
)
210+
query["fields"] = list(fields_to_use.difference(INVALID_INSIGHTS_FIELDS))
211+
212+
# Only add action_breakdowns if explicitly provided
213+
if action_breakdowns is not None:
214+
query["action_breakdowns"] = list(action_breakdowns)
215+
210216
job = execute_job(account.get_insights(params=query, is_async=True))
211217
yield list(map(process_report_item, job.get_result()))
212218
start_date = start_date.add(days=time_increment_days)

sources/facebook_ads_pipeline.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,30 @@ def load_insights() -> None:
117117
print(info)
118118

119119

120+
def load_insights_with_breakdowns() -> None:
121+
"""Shows how to load insights with custom breakdowns and action breakdowns"""
122+
pipeline = dlt.pipeline(
123+
pipeline_name="facebook_insights_breakdowns",
124+
destination="duckdb",
125+
dataset_name="facebook_insights_data",
126+
dev_mode=True,
127+
)
128+
# Load insights with age and gender breakdowns
129+
i_with_breakdowns = facebook_insights_source(
130+
initial_load_past_days=7,
131+
breakdowns="ads_insights_age_and_gender",
132+
# Uncomment to add action breakdowns:
133+
# action_breakdowns=["action_type", "action_target_id"]
134+
)
135+
info = pipeline.run(i_with_breakdowns)
136+
print(info)
137+
138+
120139
if __name__ == "__main__":
121140
# load_all_ads_objects()
122141
merge_ads_objects()
123142
# load_ads_with_custom_fields()
124143
# load_only_disapproved_ads()
125144
# load_and_enrich_objects()
126145
# load_insights()
146+
# load_insights_with_breakdowns()

tests/test_dlt_ai.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
import dlt
66
from dlt.common.utils import set_working_dir
7-
from dlt.cli import ai_command
8-
from dlt.cli.ai_command import TSupportedIde
9-
from dlt.cli.plugins import DEFAULT_VERIFIED_SOURCES_REPO
7+
from dlt._workspace.cli import _ai_command as ai_command
8+
from dlt._workspace.cli._ai_command import TSupportedIde
9+
from dlt._workspace.cli import DEFAULT_VERIFIED_SOURCES_REPO
1010

1111
from tests.utils import TEST_STORAGE_ROOT
1212

tests/test_dlt_init.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@
88

99
from dlt.sources import SourceReference
1010

11-
from dlt.cli import init_command, echo
12-
from dlt.cli.init_command import SOURCES_MODULE_NAME, utils as cli_utils, files_ops
11+
from dlt._workspace.cli import echo, _init_command as init_command
12+
from dlt._workspace.cli._init_command import (
13+
SOURCES_MODULE_NAME,
14+
utils as cli_utils,
15+
files_ops,
16+
)
1317
from dlt.reflection import names as n
1418

1519
from tests.utils import TEST_STORAGE_ROOT

tests/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
SecretsTomlProvider,
1919
)
2020
from dlt.common.configuration.specs.pluggable_run_context import (
21-
SupportsRunContext,
21+
RunContextBase,
2222
)
23+
2324
from dlt.common.runtime.run_context import DOT_DLT, RunContext
2425
from dlt.common.pipeline import LoadInfo, PipelineContext, ExtractInfo
2526
from dlt.common.storages import FileStorage
@@ -94,7 +95,7 @@ def data_dir(self) -> str:
9495
_data_dir: str
9596

9697
@classmethod
97-
def from_context(cls, ctx: SupportsRunContext) -> "MockableRunContext":
98+
def from_context(cls, ctx: RunContextBase) -> "MockableRunContext":
9899
cls_ = cls(ctx.run_dir)
99100
cls_._name = ctx.name
100101
cls_._global_dir = ctx.global_dir

0 commit comments

Comments
 (0)