I am working on an application to pull the YouTube metrics using the YouTube analytics API. This is the first time I am working with google auth flow to authenticate my app so that it can silently pull the report.
I am following the below Google published article to work out the same: https://developers.google.com/youtube/reporting/guides/authorization/server-side-web-apps
While following this article I am unable to figure out how to redirect the user to the auth_uri and obtain the auth_code.
Below is the code I have written for the auth flow so far:
API_SERVICE_NAME = 'youtubeAnalytics'
API_VERSION = 'v2'
CLIENT_SECRETS_FILE = 'C:/Users/Tushar/Documents/Serato_Video_Intelligence/client_secret_youtube.json'
def get_service():
global auth_code
global auth_uri
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_FILE,
scope='https://www.googleapis.com/auth/yt-analytics.readonly',
redirect_uri = "http://localhost:8080")
flow.params['access_type'] = 'offline'
flow.params['include_granted_scopes'] = True
auth_uri = flow.step1_get_authorize_url()
credentials = flow.step2_exchange(auth_code)
http_auth = credentials.authorize(httplib2.Http())
return build(API_SERVICE_NAME, API_VERSION, http=http_auth)
def execute_api_request(client_library_function, **kwargs):
response = client_library_function(
**kwargs
).execute()
if __name__ == '__main__':
# Disable OAuthlib's HTTPs verification when running locally.
# *DO NOT* leave this option enabled when running in production.
#os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
youtubeAnalytics = get_service()
execute_api_request(
youtubeAnalytics.reports().query,
ids='channel==XXXXXXXXXXXXXX',
startDate='2019-04-12',
endDate='2019-08-13',
filters= 'video==XXXXXXXXXXXXXX',
metrics='audienceWatchRatio,relativeRetentionPerformance',
dimensions='elapsedVideoTimeRatio'
)
When I run this code I get an error
File "C:\Users\Tushar\Documents\Serato_Video_Intelligence\youtube_auth_testing.py", line 65, in <module>
youtubeAnalytics = get_service()
File "C:\Users\Tushar\Documents\Serato_Video_Intelligence\youtube_auth_testing.py", line 40, in get_service
credentials = flow.step2_exchange(auth_code)
NameError: name 'auth_code' is not defined
I have gone through the articles on Stack Overflow and Google but have been unable to figure out what to do. I certainly know there are couple of steps that I am missing but I am unable to resolve it.
oauth2client
with Python.If my understanding is correct, how about this modification?
When the access token is retrieved by the authorization process of OAuth2, at first, it is required to authorize the scopes by own browser. When the scopes are authorize, the authorization code can be retrieved. Using this code, the refresh token and access token can be retrieved.
When your current script is modified, it becomes as follows. In this modification, please modify get_service()
.
import httplib2
from apiclient.discovery import build
from oauth2client import client
def get_service():
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_FILE,
scope='https://www.googleapis.com/auth/yt-analytics.readonly',
redirect_uri='urn:ietf:wg:oauth:2.0:oob')
flow.params['access_type'] = 'offline'
auth_uri = flow.step1_get_authorize_url()
print('Please go to this URL: {}'.format(auth_uri))
auth_code = input('Enter the authorization code: ')
credentials = flow.step2_exchange(auth_code)
http_auth = credentials.authorize(httplib2.Http())
return build(API_SERVICE_NAME, API_VERSION, http=http_auth)
Or (This is from the sample script of Reports: Query.)
def get_service():
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
credentials = flow.run_console()
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
Please go to this URL: ###
is shown in the terminal. Please copy and paste it to your browser, and please authorize the scopes. Then, please retrieve the authorization code, and please paste it to the terminal. By this flow, the access token can be retrieved.In this pattern, when the script is run, the browser is automatically opened, and when the scopes are manually authorized, the authorization code is automatically retrieved.
import httplib2
import os
from apiclient.discovery import build
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
def get_service():
SCOPES = 'https://www.googleapis.com/auth/yt-analytics.readonly'
credential_path = os.path.join("./", 'tokens.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRETS_FILE, SCOPES)
credentials = tools.run_flow(flow, store)
http = credentials.authorize(httplib2.Http())
return build(API_SERVICE_NAME, API_VERSION, http=http_auth)
tokens.json
is existing, the access token is retrieved using the refresh token in the file. By this, the authorization process using own browser is not required after 2nd run.Recently, google_auth_oauthlib
is used for the authorization process. For example, you can see it at here. When this is reflected to your script, get_service()
becomes as follows. Also you can see this flow at here.
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
def get_service():
SCOPES = ['https://www.googleapis.com/auth/yt-analytics.readonly']
TOKEN_FILE = 'token.pickle'
creds = None
if os.path.exists(TOKEN_FILE):
with open(TOKEN_FILE, 'rb') as token:
creds = pickle.load(token)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
CLIENT_SECRETS_FILE, SCOPES)
creds = flow.run_local_server()
with open(TOKEN_FILE, 'wb') as token:
pickle.dump(creds, token)
return build(API_SERVICE_NAME, API_VERSION, credentials=creds)
token.pickle
is existing, the access token is retrieved using the refresh token in the file. By this, the authorization process using own browser is not required after 2nd run.youtubeAnalytics
of youtubeAnalytics = get_service()
is used, execute_api_request()
worked fine. If in your situation, an error occurs, please confirm whether API is enabled.If I misunderstood your question and this was not the direction you want, I apologize.