Skip to content

Commit

Permalink
Source Snapchat Marketing: update authenticator package (#38574)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristoGrab authored May 23, 2024
1 parent 3ec9b4e commit aef0fc7
Show file tree
Hide file tree
Showing 6 changed files with 393 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ data:
connectorSubtype: api
connectorType: source
definitionId: 200330b2-ea62-4d11-ac6d-cfe3e3f8ab2b
dockerImageTag: 0.6.1
dockerImageTag: 0.6.2
dockerRepository: airbyte/source-snapchat-marketing
githubIssueLabel: source-snapchat-marketing
icon: snapchat.svg
Expand Down
472 changes: 382 additions & 90 deletions airbyte-integrations/connectors/source-snapchat-marketing/poetry.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
version = "0.6.1"
version = "0.6.2"
name = "source-snapchat-marketing"
description = "Source implementation for Snapchat Marketing."
authors = [ "Airbyte <contact@airbyte.io>",]
Expand All @@ -17,7 +17,7 @@ include = "source_snapchat_marketing"

[tool.poetry.dependencies]
python = "^3.9,<3.12"
airbyte-cdk = "0.80.0"
airbyte-cdk = "0.90.0"

[tool.poetry.scripts]
source-snapchat-marketing = "source_snapchat_marketing.run:run"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
from airbyte_cdk.sources.streams import Stream
from airbyte_cdk.sources.streams.core import IncrementalMixin, package_name_from_class
from airbyte_cdk.sources.streams.http import HttpStream
from airbyte_cdk.sources.streams.http.auth import Oauth2Authenticator
from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException
from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator
from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader

# https://marketingapi.snapchat.com/docs/#core-metrics
Expand Down Expand Up @@ -250,7 +249,7 @@ def stream_slices(self, **kwargs) -> Iterable[Optional[Mapping[str, Any]]]:
self.max_state = self.initial_state

parent_stream = self.parent(
authenticator=self.authenticator,
authenticator=self._session.auth,
start_date=self.start_date,
end_date=self.end_date,
action_report_time=self.action_report_time,
Expand Down Expand Up @@ -379,7 +378,7 @@ def stream_slices(self, **kwargs) -> Iterable[Optional[Mapping[str, Any]]]:
"""Each stream slice represents each entity id from parent stream"""

parent_stream = self.parent(
authenticator=self.authenticator,
authenticator=self._session.auth,
start_date=self.start_date,
end_date=self.end_date,
action_report_time=self.action_report_time,
Expand Down Expand Up @@ -757,44 +756,13 @@ class CampaignsStatsLifetime(Lifetime, Stats):
parent = Campaigns


class SnapchatOauth2Authenticator(Oauth2Authenticator):
@backoff.on_exception(
backoff.expo,
DefaultBackoffException,
on_backoff=lambda details: logger.info(
f"Caught retryable error after {details['tries']} tries. Waiting {details['wait']} seconds then retrying..."
),
max_time=300,
)
def refresh_access_token(self) -> Tuple[str, int]:
"""
returns a tuple of (access_token, token_lifespan_in_seconds)
"""
try:
response = requests.request(
method="POST",
url=self.token_refresh_endpoint,
data=self.get_refresh_request_body(),
headers=self.get_refresh_access_token_headers(),
)
response.raise_for_status()
response_json = response.json()
return response_json["access_token"], response_json["expires_in"]
except requests.exceptions.RequestException as e:
if e.response.status_code == 429 or e.response.status_code >= 500:
raise DefaultBackoffException(request=e.response.request, response=e.response)
raise
except Exception as e:
raise Exception(f"Error while refreshing access token: {e}") from e


# Source
class SourceSnapchatMarketing(AbstractSource):
"""Source Snapchat Marketing helps to retrieve the different Ad data from Snapchat business account"""

def check_connection(self, logger, config) -> Tuple[bool, any]:
try:
auth = SnapchatOauth2Authenticator(
auth = Oauth2Authenticator(
token_refresh_endpoint="https://accounts.snapchat.com/login/oauth2/access_token",
client_id=config["client_id"],
client_secret=config["client_secret"],
Expand All @@ -820,7 +788,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]:
# 2. when timezone is not specified, default account's timezone will be used automatically
default_end_date = pendulum.now().subtract(days=DELAYED_DAYS).to_date_string()
kwargs = {
"authenticator": SnapchatOauth2Authenticator(
"authenticator": Oauth2Authenticator(
token_refresh_endpoint="https://accounts.snapchat.com/login/oauth2/access_token",
client_id=config["client_id"],
client_secret=config["client_secret"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
Ads,
AdsStatsDaily,
AdsStatsLifetime,
Oauth2Authenticator,
Organizations,
SnapchatOauth2Authenticator,
SourceSnapchatMarketing,
)

Expand Down Expand Up @@ -381,7 +381,7 @@ def test_retry_get_access_token(requests_mock):
"https://accounts.snapchat.com/login/oauth2/access_token",
[{"status_code": 429}, {"status_code": 429}, {"status_code": 200, "json": {"access_token": "token", "expires_in": 3600}}],
)
auth = SnapchatOauth2Authenticator(
auth = Oauth2Authenticator(
token_refresh_endpoint="https://accounts.snapchat.com/login/oauth2/access_token",
client_id="client_id",
client_secret="client_secret",
Expand Down
1 change: 1 addition & 0 deletions docs/integrations/sources/snapchat-marketing.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ Snapchat Marketing API has limitations to 1000 items per page.

| Version | Date | Pull Request | Subject |
| :------ | :--------- | :------------------------------------------------------- | :----------------------------------------------------------------------------- |
| 0.6.2 | 2024-15-22 | [38574](https://github.com/airbytehq/airbyte/pull/38574) | Update authenticator package |
| 0.6.1 | 2024-04-24 | [36662](https://github.com/airbytehq/airbyte/pull/36662) | Schema descriptions |
| 0.6.0 | 2024-04-10 | [30586](https://github.com/airbytehq/airbyte/pull/30586) | Add `attribution_windows`,`action_report_time` as optional configurable params |
| 0.5.0 | 2024-03-19 | [36267](https://github.com/airbytehq/airbyte/pull/36267) | Pin airbyte-cdk version to `^0` |
Expand Down

0 comments on commit aef0fc7

Please sign in to comment.