Skip to content

Commit

Permalink
Merge pull request #5 from villagelabsco/feat/VD-4731-oauth
Browse files Browse the repository at this point in the history
Feat/vd 4731 oauth
  • Loading branch information
martin-village authored Aug 21, 2024
2 parents 8fdebb2 + 7d6cbe3 commit 7601305
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
30 changes: 30 additions & 0 deletions tap_hubspot/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from singer_sdk.authenticators import OAuthAuthenticator, SingletonMeta
from singer_sdk.streams import RESTStream
from typing import Any, Mapping, TypedDict, TypeGuard


class HubSpotOAuthAuthenticator(OAuthAuthenticator, metaclass=SingletonMeta):
def __init__(self, stream: RESTStream) -> None:
super().__init__(
auth_endpoint="https://api.hubapi.com/oauth/v1/token",
stream=stream,
)

@property
def oauth_request_body(self) -> dict:
return {
"client_id": self.config["client_id"],
"client_secret": self.config["client_secret"],
"grant_type": "refresh_token",
"refresh_token": self.config["refresh_token"],
}


class OAuthCredentials(TypedDict):
client_id: str
client_secret: str
refresh_token: str


def is_oauth_credentials(value: Mapping[str, Any]) -> TypeGuard[OAuthCredentials]:
return "refresh_token" in value
12 changes: 8 additions & 4 deletions tap_hubspot/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
import backoff
import pytz
import requests
from typing import Generator
from typing import Generator, Union
from singer_sdk import typing as th
from singer_sdk._singerlib.utils import strptime_to_utc
from singer_sdk.authenticators import BearerTokenAuthenticator
from singer_sdk.authenticators import BearerTokenAuthenticator, OAuthAuthenticator
from singer_sdk.exceptions import RetriableAPIError
from singer_sdk.helpers.jsonpath import extract_jsonpath
from singer_sdk.streams import RESTStream
from singer_sdk.exceptions import FatalAPIError, RetriableAPIError
from tap_hubspot.auth import HubSpotOAuthAuthenticator, is_oauth_credentials


SCHEMAS_DIR = Path(__file__).parent / Path("./schemas")
HUBSPOT_OBJECTS = [
Expand Down Expand Up @@ -48,8 +50,10 @@ def schema_filepath(self) -> Path:
return SCHEMAS_DIR / f"{self.name}.json"

@property
def authenticator(self) -> BearerTokenAuthenticator:
def authenticator(self) -> Union[BearerTokenAuthenticator, OAuthAuthenticator]:
"""Return a new authenticator object."""
if is_oauth_credentials(self.config):
return HubSpotOAuthAuthenticator(self)
return BearerTokenAuthenticator.create_for_stream(
self,
token=self.config.get("access_token"),
Expand Down Expand Up @@ -299,4 +303,4 @@ def post_process(
for subkey in keys_to_remove:
row[key].pop(subkey)

return row
return row
23 changes: 22 additions & 1 deletion tap_hubspot/tap.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,28 @@ class TapHubspot(Tap):
"access_token",
th.StringType,
required=True,
description="PRIVATE Access Token for Hubspot API",
secret=True,
description="Access Token for Hubspot API",
),
th.Property(
"client_id",
th.StringType,
required=False,
description="Client ID for Hubspot API OAuth",
),
th.Property(
"client_secret",
th.StringType,
required=False,
secret=True,
description="Client Secret for Hubspot API OAuth",
),
th.Property(
"refresh_token",
th.StringType,
required=False,
secret=True,
description="Refresh Token for Hubspot API OAuth",
),
th.Property(
"start_date",
Expand Down

0 comments on commit 7601305

Please sign in to comment.