Skip to content

Commit 0bd94c1

Browse files
🎉Source Facebook Marketing: Updated date validation process (#15327)
* Updated date validation process * Bumped docker version * auto-bump connector version [ci skip] Co-authored-by: Octavia Squidington III <[email protected]>
1 parent 43e7fbb commit 0bd94c1

File tree

8 files changed

+72
-60
lines changed

8 files changed

+72
-60
lines changed

airbyte-config/init/src/main/resources/seed/source_definitions.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@
248248
- name: Facebook Marketing
249249
sourceDefinitionId: e7778cfc-e97c-4458-9ecb-b4f2bba8946c
250250
dockerRepository: airbyte/source-facebook-marketing
251-
dockerImageTag: 0.2.58
251+
dockerImageTag: 0.2.59
252252
documentationUrl: https://docs.airbyte.io/integrations/sources/facebook-marketing
253253
icon: facebook.svg
254254
sourceType: api

airbyte-config/init/src/main/resources/seed/source_specs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@
18211821
supportsNormalization: false
18221822
supportsDBT: false
18231823
supported_destination_sync_modes: []
1824-
- dockerImage: "airbyte/source-facebook-marketing:0.2.58"
1824+
- dockerImage: "airbyte/source-facebook-marketing:0.2.59"
18251825
spec:
18261826
documentationUrl: "https://docs.airbyte.io/integrations/sources/facebook-marketing"
18271827
changelogUrl: "https://docs.airbyte.io/integrations/sources/facebook-marketing"

airbyte-integrations/connectors/source-facebook-marketing/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py"
1313
ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]
1414

1515

16-
LABEL io.airbyte.version=0.2.58
16+
LABEL io.airbyte.version=0.2.59
1717
LABEL io.airbyte.name=airbyte/source-facebook-marketing

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
Videos,
3131
)
3232

33+
from .utils import validate_end_date, validate_start_date
34+
3335
logger = logging.getLogger("airbyte")
3436

3537

@@ -58,6 +60,10 @@ def streams(self, config: Mapping[str, Any]) -> List[Type[Stream]]:
5860
:return: list of the stream instances
5961
"""
6062
config: ConnectorConfig = ConnectorConfig.parse_obj(config)
63+
64+
config.start_date = validate_start_date(config.start_date)
65+
config.end_date = validate_end_date(config.start_date, config.end_date)
66+
6167
api = API(account_id=config.account_id, access_token=config.access_token)
6268

6369
insights_args = dict(

airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
import pendulum
1111
from airbyte_cdk.sources.config import BaseConfig
1212
from facebook_business.adobjects.adsinsights import AdsInsights
13-
from pydantic import BaseModel, Field, PositiveInt, validator
14-
15-
from .utils import validate_date_field
13+
from pydantic import BaseModel, Field, PositiveInt
1614

1715
logger = logging.getLogger("airbyte")
1816

@@ -87,14 +85,6 @@ class Config:
8785
default=28,
8886
)
8987

90-
@validator("start_date")
91-
def set_start_date(cls, start_date):
92-
return validate_date_field("Start date", start_date)
93-
94-
@validator("end_date")
95-
def set_end_date(cls, end_date):
96-
return validate_date_field("End date", end_date)
97-
9888

9989
class ConnectorConfig(BaseConfig):
10090
"""Connector config"""
@@ -189,11 +179,3 @@ class Config:
189179
description="Maximum batch size used when sending batch requests to Facebook API. Most users do not need to set this field unless they specifically need to tune the connector to address specific issues or use cases.",
190180
default=50,
191181
)
192-
193-
@validator("start_date")
194-
def set_start_date(cls, start_date):
195-
return validate_date_field("Start date", start_date)
196-
197-
@validator("end_date")
198-
def set_end_date(cls, end_date):
199-
return validate_date_field("End date", end_date)

airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/utils.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,42 @@
22
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
33
#
44

5+
import logging
56
from datetime import datetime
67

78
import pendulum
89

10+
logger = logging.getLogger("airbyte")
11+
912
# Facebook store metrics maximum of 37 months old. Any time range that
1013
# older that 37 months from current date would result in 400 Bad request
1114
# HTTP response.
1215
# https://developers.facebook.com/docs/marketing-api/reference/ad-account/insights/#overview
13-
DATA_RETENTION_PERIOD = pendulum.duration(months=37)
14-
15-
16-
class ValidationDateException(Exception):
17-
def __init__(self, message, *args, **kwargs):
18-
self.message = message
19-
super().__init__(self.message, *args, **kwargs)
20-
21-
def __str__(self):
22-
return self.message
23-
24-
def __repr__(self):
25-
return self.__str__()
16+
DATA_RETENTION_PERIOD = 37
2617

2718

28-
def validate_date_field(field_name: str, date: datetime) -> datetime:
29-
pendulum_date = pendulum.instance(date)
19+
def validate_start_date(start_date: datetime) -> datetime:
20+
pendulum_date = pendulum.instance(start_date)
21+
time_zone = start_date.tzinfo
22+
current_date = pendulum.today(time_zone)
3023
if pendulum_date.timestamp() > pendulum.now().timestamp():
31-
message = f"{field_name} cannot be in the future. Please set today's date or later."
32-
raise ValidationDateException(message)
33-
elif pendulum_date.timestamp() < (pendulum.now() - DATA_RETENTION_PERIOD).timestamp():
34-
message = f"{field_name} cannot be beyond {DATA_RETENTION_PERIOD.months} months from the current date."
35-
raise ValidationDateException(message)
36-
return date
24+
message = f"The start date cannot be in the future. Set start date to today's date - {current_date}."
25+
logger.warning(message)
26+
return current_date
27+
elif pendulum_date.timestamp() < current_date.subtract(months=DATA_RETENTION_PERIOD).timestamp():
28+
current_date = pendulum.today(time_zone)
29+
message = (
30+
f"The start date cannot be beyond {DATA_RETENTION_PERIOD} months from the current date. "
31+
f"Set start date to {current_date.subtract(months=DATA_RETENTION_PERIOD)}."
32+
)
33+
logger.warning(message)
34+
return current_date.subtract(months=DATA_RETENTION_PERIOD)
35+
return start_date
36+
37+
38+
def validate_end_date(start_date: datetime, end_date: datetime) -> datetime:
39+
if start_date > end_date:
40+
message = f"The end date must be after start date. Set end date to {start_date}."
41+
logger.warning(message)
42+
return start_date
43+
return end_date

airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_utils.py

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,44 @@
44

55
import pendulum
66
import pytest
7-
from source_facebook_marketing.utils import DATA_RETENTION_PERIOD, ValidationDateException, validate_date_field
7+
from source_facebook_marketing.utils import DATA_RETENTION_PERIOD, validate_end_date, validate_start_date
88

99

1010
@pytest.mark.parametrize(
11-
"date, expected_message, raise_error",
11+
"field_name, date, expected_date, expected_messages",
1212
[
13-
(pendulum.now(), "", False),
1413
(
15-
pendulum.now() - pendulum.duration(months=DATA_RETENTION_PERIOD.months + 1),
16-
f" cannot be beyond {DATA_RETENTION_PERIOD.months} months from the current date.",
17-
True,
14+
"start_date",
15+
pendulum.today().subtract(months=DATA_RETENTION_PERIOD - 1),
16+
pendulum.today().subtract(months=DATA_RETENTION_PERIOD - 1),
17+
[],
18+
),
19+
(
20+
"start_date",
21+
pendulum.today().subtract(months=DATA_RETENTION_PERIOD + 1),
22+
pendulum.today().subtract(months=DATA_RETENTION_PERIOD),
23+
[
24+
f"The start date cannot be beyond 37 months from the current date. "
25+
f"Set start date to {pendulum.today().subtract(months=DATA_RETENTION_PERIOD)}."
26+
],
27+
),
28+
(
29+
"start_date",
30+
pendulum.today() + pendulum.duration(months=1),
31+
pendulum.today(),
32+
[f"The start date cannot be in the future. Set start date to today's date - {pendulum.today()}."],
33+
),
34+
(
35+
"end_date",
36+
pendulum.today().subtract(months=DATA_RETENTION_PERIOD),
37+
pendulum.today(),
38+
[f"The end date must be after start date. Set end date to {pendulum.today()}."],
1839
),
19-
(pendulum.now() + pendulum.duration(months=1), " cannot be in the future. Please set today's date or later.", True),
2040
],
21-
ids=["valid_date", f"date in the past by {DATA_RETENTION_PERIOD.months} months", "date in future"],
2241
)
23-
def test_validate_date_field(date, expected_message, raise_error):
24-
field_name = "test_field_name"
25-
26-
if raise_error:
27-
with pytest.raises(ValidationDateException) as error:
28-
assert validate_date_field(field_name, date)
29-
assert str(error.value) == field_name + expected_message
30-
else:
31-
assert validate_date_field(field_name, date)
42+
def test_date_validators(caplog, field_name, date, expected_date, expected_messages):
43+
if field_name == "start_date":
44+
assert validate_start_date(date) == expected_date
45+
elif field_name == "end_date":
46+
assert validate_end_date(expected_date, date) == expected_date
47+
assert caplog.messages == expected_messages

docs/integrations/sources/facebook-marketing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ Please be informed that the connector uses the `lookback_window` parameter to pe
120120

121121
| Version | Date | Pull Request | Subject |
122122
|:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
123+
| 0.2.59 | 2022-08-04 | [15327](https://github.com/airbytehq/airbyte/pull/15327) | Shift date validation from config validation to stream method |
123124
| 0.2.58 | 2022-07-25 | [15012](https://github.com/airbytehq/airbyte/pull/15012) | Add `DATA_RETENTION_PERIOD`validation and fix `failed_delivery_checks` field schema type issue |
124125
| 0.2.57 | 2022-07-25 | [14831](https://github.com/airbytehq/airbyte/pull/14831) | Update Facebook SDK to version 14.0.0 |
125126
| 0.2.56 | 2022-07-19 | [14831](https://github.com/airbytehq/airbyte/pull/14831) | Add future `start_date` and `end_date` validation |

0 commit comments

Comments
 (0)