google.auth.exceptions.RefreshError: Invalid Client
I am working on a project to let a client authorize their google ads account, and then use those authorized credentials to download data on their behalf. I have a webapp that successfully Authorizes the app to do things on the clients behalf. This generates an access code that I then trade for two credentials, an access token and a refresh token. This refresh token then gets passed to a database, where a separate app attempts to query the googleAds API. It is my understanding that the Google Oauth engine only needs the refresh token.
I am trying to authorize by use of load_from_dict() or load_from_env() methods of the GoogleAdsClient class. Both yield the same error: google.auth.exceptions.RefreshError: ('invalid_client: Unauthorized', {'error': 'invalid_client', 'error_description': 'Unauthorized'})
I have verified the developer_token, client_id, and client_secret are all accurate to what is in the API console. I have also verified the refresh_token is being passed correctly to the credential dict.
I am really at a loss on where to go from here. I have read many stack overflow threads with similar titles, and yet I am still stuck at the same place.
Here are some relevant links.
Google Identity and Server side web apps
Google's example of an API call
Relevant code
class GoogleAds: def __init__(self): self.scope = ['https://www.googleapis.com/auth/adwords'] self.client_id = os.getenv('GOOGLE_ADS_CLIENT_ID') self.client_secret = os.getenv('GOOGLE_ADS_CLIENT_SECRET') self.developer_token = os.getenv('GOOGLE_ADS_DEVELOPER_TOKEN') self.refresh_token = os.getenv('GOOGLE_ADS_REFRESH_TOKEN') def authorize(self): credentials = { "developer_token": self.developer_token, "refresh_token": self.refresh_token, "client_id": self.client_id, "client_secret": self.client_secret, "use_proto_plus":"True", "grant_type": "refresh_token", } print(credentials) googleads_client = GoogleAdsClient.load_from_dict(credentials) service = googleads_client.get_service("GoogleAdsService") request = googleads_client.get_type("SearchGoogleAdsRequest") return service, request