From 2ac0c7e9d8ac2e1b1b923d1a67ffd9422159835b Mon Sep 17 00:00:00 2001 From: Andy Diamondstein Date: Tue, 24 Oct 2017 09:43:38 -0400 Subject: [PATCH] Update auth libraries, add snippet metadata opts The oauth2client library is deprecated. This update changes the sample to use the google-auth and google-auth-oauthlib libraries instead. In addition, the code now supports other arguments for updating snippet metadata (title, description, tags). The --tags argument replaces the existing tags, while the --add_tag argument appends a tag to the current list. --- python/update_video.py | 124 ++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/python/update_video.py b/python/update_video.py index 2d428e6b..58609cb1 100644 --- a/python/update_video.py +++ b/python/update_video.py @@ -1,14 +1,16 @@ #!/usr/bin/python -import httplib2 +# Update the snippet metadata for a video. Sample usage: +# python update_video.py --video_id= --tags="" --title="New title" --description="New description" + +import argparse import os -import sys -from apiclient.discovery import build -from apiclient.errors import HttpError -from oauth2client.client import flow_from_clientsecrets -from oauth2client.file import Storage -from oauth2client.tools import argparser, run_flow +import google.oauth2.credentials +import google_auth_oauthlib.flow +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError +from google_auth_oauthlib.flow import InstalledAppFlow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains @@ -21,89 +23,87 @@ # https://developers.google.com/youtube/v3/guides/authentication # For more information about the client_secrets.json file format, see: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets -CLIENT_SECRETS_FILE = "client_secrets.json" +CLIENT_SECRETS_FILE = 'client_secret.json' # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account. -YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube" -YOUTUBE_API_SERVICE_NAME = "youtube" -YOUTUBE_API_VERSION = "v3" - -# This variable defines a message to display if the CLIENT_SECRETS_FILE is -# missing. -MISSING_CLIENT_SECRETS_MESSAGE = """ -WARNING: Please configure OAuth 2.0 - -To make this sample run you will need to populate the client_secrets.json file -found at: - - %s - -with information from the {{ Cloud Console }} -{{ https://cloud.google.com/console }} - -For more information about the client_secrets.json file format, please visit: -https://developers.google.com/api-client-library/python/guide/aaa_client_secrets -""" % os.path.abspath(os.path.join(os.path.dirname(__file__), - CLIENT_SECRETS_FILE)) +SCOPES = ['https://www.googleapis.com/auth/youtube'] +API_SERVICE_NAME = 'youtube' +API_VERSION = 'v3' -def get_authenticated_service(args): - flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, - scope=YOUTUBE_READ_WRITE_SCOPE, - message=MISSING_CLIENT_SECRETS_MESSAGE) +# Authorize the request and store authorization credentials. +def get_authenticated_service(): + flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES) + credentials = flow.run_console() + return build(API_SERVICE_NAME, API_VERSION, credentials = credentials) - storage = Storage("%s-oauth2.json" % sys.argv[0]) - credentials = storage.get() - - if credentials is None or credentials.invalid: - credentials = run_flow(flow, storage, args) - - return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, - http=credentials.authorize(httplib2.Http())) - -def update_video(youtube, options): +def update_video(youtube, args): # Call the API's videos.list method to retrieve the video resource. videos_list_response = youtube.videos().list( - id=options.video_id, + id=args.video_id, part='snippet' ).execute() - # If the response does not contain an array of "items" then the video was + # If the response does not contain an array of 'items' then the video was # not found. - if not videos_list_response["items"]: - print "Video '%s' was not found." % options.video_id + if not videos_list_response['items']: + print 'Video "%s" was not found.' % args.video_id sys.exit(1) # Since the request specified a video ID, the response only contains one # video resource. This code extracts the snippet from that resource. - videos_list_snippet = videos_list_response["items"][0]["snippet"] + videos_list_snippet = videos_list_response['items'][0]['snippet'] + + # Set video title, description, default language if specified in args. + if args.title: + videos_list_snippet['title'] = args.title + if args.description: + videos_list_snippet['description'] = args.description # Preserve any tags already associated with the video. If the video does # not have any tags, create a new array. Append the provided tag to the # list of tags associated with the video. - if "tags" not in videos_list_snippet: - videos_list_snippet["tags"] = [] - videos_list_snippet["tags"].append(options.tag) + if 'tags' not in videos_list_snippet: + videos_list_snippet['tags'] = [] + if args.tags: + videos_list_snippet['tags'] = args.tags.split(',') + elif args.add_tag: + videos_list_snippet['tags'].append(args.add_tag) + + print(videos_list_snippet); # Update the video resource by calling the videos.update() method. videos_update_response = youtube.videos().update( part='snippet', body=dict( snippet=videos_list_snippet, - id=options.video_id + id=args.video_id )).execute() -if __name__ == "__main__": - argparser.add_argument("--video-id", help="ID of video to update.", + print('The updated video metadata is:\n' + + 'Title: ' + videos_update_response['snippet']['title'] + '\n') + if videos_update_response['snippet']['description']: + print ('Description: ' + + videos_update_response['snippet']['description'] + '\n') + if videos_update_response['snippet']['tags']: + print ('Tags: ' + ','.join(videos_update_response['snippet']['tags']) + '\n') + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--video_id', help='ID of video to update.', required=True) - argparser.add_argument("--tag", default="youtube", - help="Additional tag to add to video.") - args = argparser.parse_args() - - youtube = get_authenticated_service(args) + parser.add_argument('--tags', + help='Comma-separated list of tags relevant to the video. This argument ' + + 'replaces the existing list of tags.') + parser.add_argument('--add_tag', help='Additional tag to add to video. ' + + 'This argument does not affect current tags.') + parser.add_argument('--title', help='Title of the video.') + parser.add_argument('--description', help='Description of the video.') + args = parser.parse_args() + + youtube = get_authenticated_service() try: update_video(youtube, args) except HttpError, e: - print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) - else: - print "Tag '%s' was added to video id '%s'." % (args.tag, args.video_id) + print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content) + print 'Tag "%s" was added to video id "%s".' % (args.add_tag, args.video_id)