From 2d2671c15cdc99a6294a476e658419109f36cd95 Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Mon, 11 Mar 2024 16:10:12 -0400 Subject: [PATCH 1/3] remove access token from oauth creds --- README.md | 2 +- tap_google_analytics/tap.py | 24 +++++++----------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3f34392..f777a11 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ pipx install tap-google-analytics If you're setting up `tap-google-analytics` for your own organization and only plan to extract from a handful of different views in the same limited set of properties, Service Account based authorization is the simplest. When you create a service account Google gives you a json file with that service account's credentials called the `client_secrets.json`, and that's all you need to pass to this tap, and you only have to do it once, so this is the recommended way of configuring `tap-google-analytics`. -If you're building something where a wide variety of users need to be able to give access to their Google Analytics, `tap-google-analytics` can use an `access_token` granted by those users to authorize it's requests to Google. This `access_token` is produced by a normal Google OAuth flow, but this flow is outside the scope of `tap-google-analytics`. This is useful if you're integrating `tap-google-analytics` with another system, like Stitch Data might do to allow users to configure their extracts themselves without manual config setup. This tap expects an `access_token`, `refresh_token`, `client_id` and `client_secret` to be passed to it in order to authenticate as the user who granted the token and then access their data. +If you're building something where a wide variety of users need to be able to give access to their Google Analytics, `tap-google-analytics` can use an `access_token` granted by those users to authorize it's requests to Google. This `access_token` is produced by a normal Google OAuth flow, but this flow is outside the scope of `tap-google-analytics`. This is useful if you're integrating `tap-google-analytics` with another system, like Arch does to allow users to configure their extracts themselves without manual config setup. This tap expects an `access_token`, `refresh_token`, `client_id` and `client_secret` to be passed to it in order to authenticate as the user who granted the token and then access their data. ## Required Analytics Reporting APIs & OAuth Scopes diff --git a/tap_google_analytics/tap.py b/tap_google_analytics/tap.py index 4b0c836..e191569 100644 --- a/tap_google_analytics/tap.py +++ b/tap_google_analytics/tap.py @@ -10,6 +10,7 @@ from oauth2client.service_account import ServiceAccountCredentials from singer_sdk import Stream, Tap from singer_sdk import typing as th # JSON schema typing helpers +from google.oauth2.credentials import Credentials as OAuthCredentials from tap_google_analytics.client import GoogleAnalyticsStream @@ -53,15 +54,6 @@ class TapGoogleAnalytics(Tap): th.Property( "oauth_credentials", th.ObjectType( - th.Property( - "access_token", - th.StringType, - description=( - "Google Analytics Access Token. See " - "https://developers.google.com/analytics/devguides/reporting/" - "core/v4/authorization#OAuth2Authorizing." - ), - ), th.Property( "refresh_token", th.StringType, @@ -107,14 +99,12 @@ class TapGoogleAnalytics(Tap): def _initialize_credentials(self): if self.config.get("oauth_credentials"): - return GoogleCredentials( - access_token=self.config["oauth_credentials"]["access_token"], - refresh_token=self.config["oauth_credentials"]["refresh_token"], - client_id=self.config["oauth_credentials"]["client_id"], - client_secret=self.config["oauth_credentials"]["client_secret"], - token_expiry=None, # let the library refresh the token if it is expired - token_uri="https://accounts.google.com/o/oauth2/token", - user_agent="tap-google-analytics (via singer.io)", + return OAuthCredentials.from_authorized_user_info( + { + "client_id": self.config["oauth_credentials"]["client_id"], + "client_secret": self.config["oauth_credentials"]["client_secret"], + "refresh_token": self.config["oauth_credentials"]["refresh_token"], + } ) elif self.config.get("key_file_location"): return ServiceAccountCredentials.from_json_keyfile_name( From 8637fb90b0e1ccd7290f98f175044efcd0157126 Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Mon, 11 Mar 2024 16:12:47 -0400 Subject: [PATCH 2/3] remove unused import --- tap_google_analytics/tap.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tap_google_analytics/tap.py b/tap_google_analytics/tap.py index e191569..15eacf3 100644 --- a/tap_google_analytics/tap.py +++ b/tap_google_analytics/tap.py @@ -6,7 +6,6 @@ from typing import List, Tuple from googleapiclient.discovery import build -from oauth2client.client import GoogleCredentials from oauth2client.service_account import ServiceAccountCredentials from singer_sdk import Stream, Tap from singer_sdk import typing as th # JSON schema typing helpers From 6f8de97ee19b9f618d38bd0c0e542d166c7528b6 Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Mon, 11 Mar 2024 16:17:24 -0400 Subject: [PATCH 3/3] fix imports sort linting --- tap_google_analytics/tap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tap_google_analytics/tap.py b/tap_google_analytics/tap.py index 15eacf3..6b8ee26 100644 --- a/tap_google_analytics/tap.py +++ b/tap_google_analytics/tap.py @@ -5,11 +5,11 @@ from pathlib import Path from typing import List, Tuple +from google.oauth2.credentials import Credentials as OAuthCredentials from googleapiclient.discovery import build from oauth2client.service_account import ServiceAccountCredentials from singer_sdk import Stream, Tap from singer_sdk import typing as th # JSON schema typing helpers -from google.oauth2.credentials import Credentials as OAuthCredentials from tap_google_analytics.client import GoogleAnalyticsStream