Skip to content

Commit d09994f

Browse files
committed
fix SAT
1 parent 15e73f1 commit d09994f

File tree

3 files changed

+55
-91
lines changed

3 files changed

+55
-91
lines changed

airbyte-integrations/connectors/source-facebook-marketing/acceptance-test-config.yml

-9
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,3 @@ tests:
2020
future_state_path: "integration_tests/future_state.json"
2121
full_refresh:
2222
- config_path: "secrets/config.json"
23-
# Ad Insights API has estimated metrics in response, which is calculated based on another metrics.
24-
# Sometimes API doesn't return estimated metrics. E.g, cost_per_estimated_ad_recallers is calculated
25-
# as total amount spent divided by estimated ad recall lift rate. When second metric is equal to zero
26-
# API may or may not return value. Such behavior causes sequential reads test failing.
27-
# Because one read response contains this metric, and other doesn't.
28-
# Therefore, it's needed to ignore fields like this in API responses.
29-
ignored_fields:
30-
"ads_insights_age_and_gender": ["cost_per_estimated_ad_recallers"]
31-
"ad_creatives": ["thumbnail_url"]

airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json

+49-80
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,62 @@
55
"title": "Source Facebook Marketing",
66
"type": "object",
77
"properties": {
8-
"account_id": {
9-
"title": "Account Id",
10-
"description": "The Facebook Ad account ID to use when pulling data from the Facebook Marketing API.",
11-
"type": "string"
12-
},
13-
"access_token": {
14-
"title": "Access Token",
15-
"description": "The value of the access token generated. See the <a href=\"https://docs.airbyte.io/integrations/sources/facebook-marketing\">docs</a> for more information",
16-
"airbyte_secret": true,
17-
"type": "string"
18-
},
198
"start_date": {
209
"title": "Start Date",
2110
"description": "The date from which you'd like to replicate data for AdCreatives and AdInsights APIs, in the format YYYY-MM-DDT00:00:00Z. All data generated after this date will be replicated.",
11+
"order": 0,
2212
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$",
23-
"examples": ["2017-01-25T00:00:00Z"],
13+
"examples": [
14+
"2017-01-25T00:00:00Z"
15+
],
2416
"type": "string",
2517
"format": "date-time"
2618
},
2719
"end_date": {
2820
"title": "End Date",
2921
"description": "The date until which you'd like to replicate data for AdCreatives and AdInsights APIs, in the format YYYY-MM-DDT00:00:00Z. All data generated between start_date and this date will be replicated. Not setting this option will result in always syncing the latest data.",
22+
"order": 1,
3023
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$",
31-
"examples": ["2017-01-26T00:00:00Z"],
24+
"examples": [
25+
"2017-01-26T00:00:00Z"
26+
],
3227
"type": "string",
3328
"format": "date-time"
3429
},
35-
"fetch_thumbnail_images": {
36-
"title": "Fetch Thumbnail Images",
37-
"description": "In each Ad Creative, fetch the thumbnail_url and store the result in thumbnail_data_url",
38-
"default": false,
39-
"type": "boolean"
30+
"account_id": {
31+
"title": "Account ID",
32+
"description": "The Facebook Ad account ID to use when pulling data from the Facebook Marketing API.",
33+
"order": 2,
34+
"examples": [
35+
"111111111111111"
36+
],
37+
"type": "string"
38+
},
39+
"access_token": {
40+
"title": "Access Token",
41+
"description": "The value of the access token generated. See the <a href=\"https://docs.airbyte.io/integrations/sources/facebook-marketing\">docs</a> for more information",
42+
"order": 3,
43+
"airbyte_secret": true,
44+
"type": "string"
4045
},
4146
"include_deleted": {
4247
"title": "Include Deleted",
43-
"description": "Include data from deleted campaigns, ads, and adsets",
48+
"description": "Include data from deleted Campaigns, Ads, and AdSets",
4449
"default": false,
50+
"order": 4,
4551
"type": "boolean"
4652
},
47-
"insights_lookback_window": {
48-
"title": "Insights Lookback Window",
49-
"description": "The attribution window for the actions",
50-
"default": 28,
51-
"minimum": 0,
52-
"maximum": 28,
53-
"type": "integer"
54-
},
55-
"insights_days_per_job": {
56-
"title": "Insights Days Per Job",
57-
"description": "Number of days to sync in one job (the more data you have, the smaller this parameter should be)",
58-
"default": 7,
59-
"minimum": 1,
60-
"maximum": 30,
61-
"type": "integer"
53+
"fetch_thumbnail_images": {
54+
"title": "Fetch Thumbnail Images",
55+
"description": "In each Ad Creative, fetch the thumbnail_url and store the result in thumbnail_data_url",
56+
"default": false,
57+
"order": 5,
58+
"type": "boolean"
6259
},
6360
"custom_insights": {
6461
"title": "Custom Insights",
65-
"description": "A list wich contains insights entries, each entry must have a name and can contains fields, breakdowns or action_breakdowns)",
62+
"description": "A list which contains insights entries, each entry must have a name and can contains fields, breakdowns or action_breakdowns)",
63+
"order": 6,
6664
"type": "array",
6765
"items": {
6866
"title": "InsightConfig",
@@ -101,61 +99,32 @@
10199
}
102100
}
103101
},
104-
"required": ["name"]
102+
"required": [
103+
"name"
104+
]
105105
}
106106
}
107107
},
108-
"required": ["account_id", "access_token", "start_date"],
109-
"definitions": {
110-
"InsightConfig": {
111-
"title": "InsightConfig",
112-
"type": "object",
113-
"properties": {
114-
"name": {
115-
"title": "Name",
116-
"description": "The name value of insight",
117-
"type": "string"
118-
},
119-
"fields": {
120-
"title": "Fields",
121-
"description": "A list of chosen fields for fields parameter",
122-
"default": [],
123-
"type": "array",
124-
"items": {
125-
"type": "string"
126-
}
127-
},
128-
"breakdowns": {
129-
"title": "Breakdowns",
130-
"description": "A list of chosen breakdowns for breakdowns",
131-
"default": [],
132-
"type": "array",
133-
"items": {
134-
"type": "string"
135-
}
136-
},
137-
"action_breakdowns": {
138-
"title": "Action Breakdowns",
139-
"description": "A list of chosen action_breakdowns for action_breakdowns",
140-
"default": [],
141-
"type": "array",
142-
"items": {
143-
"type": "string"
144-
}
145-
}
146-
},
147-
"required": ["name"]
148-
}
149-
}
108+
"required": [
109+
"start_date",
110+
"account_id",
111+
"access_token"
112+
]
150113
},
151114
"supportsIncremental": true,
152-
"supported_destination_sync_modes": ["append"],
115+
"supported_destination_sync_modes": [
116+
"append"
117+
],
153118
"authSpecification": {
154119
"auth_type": "oauth2.0",
155120
"oauth2Specification": {
156121
"rootObject": [],
157122
"oauthFlowInitParameters": [],
158-
"oauthFlowOutputParameters": [["access_token"]]
123+
"oauthFlowOutputParameters": [
124+
[
125+
"access_token"
126+
]
127+
]
159128
}
160129
}
161130
}

airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/insights_streams.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import copy
66
import logging
7-
from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Iterator
7+
from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Iterator, Union
88

99
import airbyte_cdk.sources.utils.casing as casing
1010
import pendulum
@@ -24,7 +24,6 @@ class AdsInsights(FBMarketingIncrementalStream):
2424
"""doc: https://developers.facebook.com/docs/marketing-api/insights"""
2525

2626
cursor_field = "date_start"
27-
primary_key = None
2827

2928
ALL_ACTION_ATTRIBUTION_WINDOWS = [
3029
"1d_click",
@@ -84,6 +83,11 @@ def name(self) -> str:
8483
name = self._new_class_name or self.__class__.__name__
8584
return casing.camel_to_snake(name)
8685

86+
@property
87+
def primary_key(self) -> Optional[Union[str, List[str], List[List[str]]]]:
88+
"""Build complex PK based on slices and breakdowns"""
89+
return ["date_start", "ad_id"] + self.breakdowns
90+
8791
def _get_campaign_ids(self, params) -> List[str]:
8892
campaign_params = copy.deepcopy(params)
8993
campaign_params.update(fields=["campaign_id"], level="campaign")

0 commit comments

Comments
 (0)