Search code examples
pythonyoutube-apigoogle-oauthgoogle-api-client

Google API Authorization (Service Account) Error: HttpAccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request


I'm attempting to connect to the YouTube Analytics API using Python. When I go to Google's Developer Console in the Credentials tab I click on the Create credentials drop-down menu and select Help me choose. I click on the API I want to use (YouTube Analytics API), where I will be calling from (Other non-UI (e.g. cron job, daemon)), what data I will be accessing (Application Data), and then whether I'm using Google App Engine (no). I click on the button to see which credentials I need and it tells me You alread have credentials that are suitable for this purpose.

I have a Service account that I use to connect to the Google Search Console API to access data for multiple sites my company owns. Because we have multiple sites I use delegated credentials based on my email address. This is the code I use to authenticate to the Search Console API:

from httplib2 import Http
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build

scopes = ['https://www.googleapis.com/auth/webmasters.readonly']
credentials = ServiceAccountCredentials.from_json_keyfile_name('keyfile.json', scopes=scopes)

delegated_credentials = credentials.create_delegated('<my-email>')
http_auth = delegated_credentials.authorize(Http())

webmasters_service = build('webmasters', 'v3', http=http_auth)

Now, I'm trying to use a similar approach with the YouTube Analytics API but I'm getting this error: HttpAccessTokenRefreshError: unauthorized_client: Unauthorized client or scope in request.. Here's my code:

from httplib2 import Http
from oauth2client.service_account import ServiceAccountCredentials
from apiclient.discovery import build

START_DATE = "2016-09-01"
END_DATE = "2016-09-30"

scopes = ['https://www.googleapis.com/auth/yt-analytics.readonly']
credentials = ServiceAccountCredentials.from_json_keyfile_name('keyfile.json', scopes=scopes)

delegated_credentials = credentials.create_delegated('<my-email>')
http_auth = delegated_credentials.authorize(Http())

youtube_service = build('youtubeAnalytics', 'v1', http=http_auth)

analytics_query_response = youtube_service.reports().query(
    ids="channel==<my-youtube-channel-id>",
    metrics="views",
    start_date=START_DATE,
    end_date=END_DATE
).execute()

The keyfile.json is the same file (containing the Service account credentials) that I use to connect to the Search Console API. I even tried created a new Service account and used those credentials but I didn't have any luck. And yes, I've enabled the all of the YouTube APIs in the developer console.

Do you have any idea why I'm getting the HttpAccessTokenRefreshError: unauthorized_client: ... error?

edit: Previously I used an OAuth ID as opposed to a Service account, when I ran my script a browser tab was presented and I had to choose an account. I was presented with two options: one was my email, the other was the YouTube account that I was added as a manager. Do you think that I'm getting that error because I'm using my email address to generate credentials (and not the YouTube account)?

edit2: It appears that the YouTube account may not fall under the umbrella of our Google Apps domain. So, this may be why I can't authorize using my email address, even though I've been made a Manager of that YouTube account with that email address.


Solution

  • I found on this documentation that you cannot use Service account with YouTube Analytics API.

    It is stated here that:

    The service account flow supports server-to-server interactions that do not access user information. However, the YouTube Analytics API does not support this flow. Since there is no way to link a Service Account to a YouTube account, attempts to authorize requests with this flow will generate an error.

    I also found it in this thread answered by a Googler.

    For more information, check this SO question.