I am writing a simple python script that gets a YouTube video duration using google-API. This is the code I wrote:
# imports
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
import aniso8601
scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
# File name which has the credentials(API/OAuth)
client_secrets_file = "MY_FILE_NAME.json"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(api_service_name, api_version, credentials=credentials)
request = youtube.videos().list(
part="contentDetails",
id="CbxQWAFv7sA"
)
response = request.execute()
duration_in_iso_8601 = response['items'][0]['contentDetails']['duration']
duration_in_seconds = aniso8601.parse_duration(duration_in_iso_8601).seconds
print(duration_in_seconds)
Now, everything works fine except the fact that every time I run the script I am asked to enter an authorization code:
Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=MY_ID.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&state=i4RuG2QRXmef9t5MQUoOOqSXGhvMM5&prompt=consent&access_type=offline
Enter the authorization code:
My goal is that eventually the script will be automated on different devices, so the above interrupts the flow. I wanted to know, Is there any way to disable this prompt? If not, is there any other way to implement this such that the authorization won't interfere the flow? Thanks a lot!
Actually, I don't want any authentication, if possible using this API.
You need to understand that you are accessing private user data. In order to access private user data you need the permission of the user who owns that data. TO get that permission or consent we use Oauth2. There is no other option for the YouTube API you will need to request consent.
The method you are accessing video.list is actually based upon public data not private user data. Which means you should be using an API key to access it. How to create a YouTube API key
youtube = build('youtube', 'v3', developerKey='api_key')
If you do need to access private user data though. The Google analytics API has a very nice example for python. It shows how to store your credentials in a .dat file. This code is single user but you could change it so that each users credentials will be stored in a different file.
I did my best to alter it a bit for you for YouTube API. Let me know if you have any issues.
SCOPES = ['https://www.googleapis.com/auth/youtube.readonly']
CLIENT_SECRETS_PATH = 'client_secrets.json' # Path to client_secrets.json file.
def initialize_youtube():
"""Initializes the youtube service object.
Returns:
analytics an authorized youtube service object.
"""
# Parse command-line arguments.
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
flags = parser.parse_args([])
# Set up a Flow object to be used if we need to authenticate.
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_PATH, scope=SCOPES,
message=tools.message_if_missing(CLIENT_SECRETS_PATH))
# Prepare credentials, and authorize HTTP object with them.
# If the credentials don't exist or are invalid run through the native client
# flow. The Storage object will ensure that if successful the good
# credentials will get written back to a file.
storage = file.Storage('youtube.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow, storage, flags)
http = credentials.authorize(http=httplib2.Http())
# Build the service object.
youtube = build('youtube', 'v3', http=http)
return youtube