The following code samples, which use the Google APIs Client Library for Python, are available for the YouTube Data API. You can download these code samples from the python
folder of the YouTube APIs code sample repository on GitHub.
Post a channel bulletin
The following code sample calls the API's activities.insert
method to post a bulletin to the channel associated with the request.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # This method calls the API's youtube.activities.insert method to post the # channel bulletin. def post_bulletin(youtube, args): body = dict( snippet=dict( description=args.message ) ) if args.video_id: body["contentDetails"] = dict( bulletin=dict( resourceId=dict( kind="youtube#video", videoId=args.video_id ) ) ) if args.playlist_id: body["contentDetails"] = dict( bulletin=dict( resourceId=dict( kind="youtube#playlist", playlistId=args.playlist_id ) ) ) youtube.activities().insert( part=",".join(body.keys()), body=body ).execute() if __name__ == "__main__": argparser.add_argument("--message", required=True, help="Text of message to post.") argparser.add_argument("--video-id", help="Optional ID of video to post.") argparser.add_argument("--playlist-id", help="Optional ID of playlist to post.") args = argparser.parse_args() # You can post a message with or without an accompanying video or playlist. # However, you can't post a video and a playlist at the same time. if args.video_id and args.playlist_id: exit("You cannot post a video and a playlist at the same time.") youtube = get_authenticated_service(args) try: post_bulletin(youtube, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "The bulletin was posted to your channel."
Create and manage YouTube video caption tracks
The following code sample demonstrates how to use the following API methods to create and manage YouTube video caption tracks:
- It calls the
captions.insert
method with theisDraft
parameter set totrue
to upload a caption track in draft status. - It calls the
captions.list
method with thevideoId
parameter to retrieve video caption tracks. - It calls the
captions.update
method with the caption in the request body to update a caption track. - It calls the
captions.download
method to download the caption track. - It calls the
captions.delete
method to delete the caption track, using theid
parameter to identify the caption track.
#!/usr/bin/python # Usage example: # python captions.py --videoid='<video_id>' --name='<name>' --file='<file>' --language='<language>' --action='action' import httplib2 import os import sys from apiclient.discovery import build_from_document from apiclient.errors import HttpError from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl" 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: credentials = run_flow(flow, storage, args) # Trusted testers can download this discovery document from the developers page # and it should be in the same directory with the code. with open("youtube-v3-api-captions.json", "r") as f: doc = f.read() return build_from_document(doc, http=credentials.authorize(httplib2.Http())) # Call the API's captions.list method to list the existing caption tracks. def list_captions(youtube, video_id): results = youtube.captions().list( part="snippet", videoId=video_id ).execute() for item in results["items"]: id = item["id"] name = item["snippet"]["name"] language = item["snippet"]["language"] print "Caption track '%s(%s)' in '%s' language." % (name, id, language) return results["items"] # Call the API's captions.insert method to upload a caption track in draft status. def upload_caption(youtube, video_id, language, name, file): insert_result = youtube.captions().insert( part="snippet", body=dict( snippet=dict( videoId=video_id, language=language, name=name, isDraft=True ) ), media_body=file ).execute() id = insert_result["id"] name = insert_result["snippet"]["name"] language = insert_result["snippet"]["language"] status = insert_result["snippet"]["status"] print "Uploaded caption track '%s(%s) in '%s' language, '%s' status." % (name, id, language, status) # Call the API's captions.update method to update an existing caption track's draft status # and publish it. If a new binary file is present, update the track with the file as well. def update_caption(youtube, caption_id, file): update_result = youtube.captions().update( part="snippet", body=dict( id=caption_id, snippet=dict( isDraft=False ) ), media_body=file ).execute() name = update_result["snippet"]["name"] isDraft = update_result["snippet"]["isDraft"] print "Updated caption track '%s' draft status to be: '%s'" % (name, isDraft) if file: print "and updated the track with the new uploaded file." # Call the API's captions.download method to download an existing caption track. def download_caption(youtube, caption_id, tfmt): subtitle = youtube.captions().download( id=caption_id, tfmt=tfmt ).execute() print "First line of caption track: %s" % (subtitle) # Call the API's captions.delete method to delete an existing caption track. def delete_caption(youtube, caption_id): youtube.captions().delete( id=caption_id ).execute() print "caption track '%s' deleted succesfully" % (caption_id) if __name__ == "__main__": # The "videoid" option specifies the YouTube video ID that uniquely # identifies the video for which the caption track will be uploaded. argparser.add_argument("--videoid", help="Required; ID for video for which the caption track will be uploaded.") # The "name" option specifies the name of the caption trackto be used. argparser.add_argument("--name", help="Caption track name", default="YouTube for Developers") # The "file" option specifies the binary file to be uploaded as a caption track. argparser.add_argument("--file", help="Captions track file to upload") # The "language" option specifies the language of the caption track to be uploaded. argparser.add_argument("--language", help="Caption track language", default="en") # The "captionid" option specifies the ID of the caption track to be processed. argparser.add_argument("--captionid", help="Required; ID of the caption track to be processed") # The "action" option specifies the action to be processed. argparser.add_argument("--action", help="Action", default="all") args = argparser.parse_args() if (args.action in ('upload', 'list', 'all')): if not args.videoid: exit("Please specify videoid using the --videoid= parameter.") if (args.action in ('update', 'download', 'delete')): if not args.captionid: exit("Please specify captionid using the --captionid= parameter.") if (args.action in ('upload', 'all')): if not args.file: exit("Please specify a caption track file using the --file= parameter.") if not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") youtube = get_authenticated_service(args) try: if args.action == 'upload': upload_caption(youtube, args.videoid, args.language, args.name, args.file) elif args.action == 'list': list_captions(youtube, args.videoid) elif args.action == 'update': update_caption(youtube, args.captionid, args.file); elif args.action == 'download': download_caption(youtube, args.captionid, 'srt') elif args.action == 'delete': delete_caption(youtube, args.captionid); else: # All the available methods are used in sequence just for the sake of an example. upload_caption(youtube, args.videoid, args.language, args.name, args.file) captions = list_captions(youtube, args.videoid) if captions: first_caption_id = captions[0]['id']; update_caption(youtube, first_caption_id, None); download_caption(youtube, first_caption_id, 'srt') delete_caption(youtube, first_caption_id); except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Created and managed caption tracks."
Upload a banner image and set as channel's banner
The following code sample calls the API's channelBanners.insert
method to upload an image. With the returned URL, the sample calls channels.update
method to update channel's banner to this image.
#!/usr/bin/python # This sample sets a custom banner to user's channel by: # # 1. Uploading a banner image with "youtube.channelBanners.insert" method via resumable upload # 2. Getting user's channel object with "youtube.channels.list" method and "mine" parameter # 3. Updating channel's banner external URL with "youtube.channels.update" method # # @author Ibrahim Ulukaya import httplib import httplib2 import os import random import sys import time from apiclient.discovery import build from apiclient.errors import HttpError from apiclient.http import MediaFileUpload from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # Explicitly tell the underlying HTTP transport library not to retry, since # we are handling retry logic ourselves. httplib2.RETRIES = 1 # Maximum number of times to retry before giving up. MAX_RETRIES = 10 # Always retry when these exceptions are raised. RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected, httplib.IncompleteRead, httplib.ImproperConnectionState, httplib.CannotSendRequest, httplib.CannotSendHeader, httplib.ResponseNotReady, httplib.BadStatusLine) # Always retry when an apiclient.errors.HttpError with one of these status # codes is raised. RETRIABLE_STATUS_CODES = [500, 502, 503, 504] # CLIENT_SECRETS_FILE, name of a file containing the OAuth 2.0 information for # this application, including client_id and client_secret. You can acquire an # ID/secret pair from the APIs & auth tab at # https://cloud.google.com/console # For more information about using OAuth2 to access Google APIs, please visit: # https://developers.google.com/accounts/docs/OAuth2 # For more information about the client_secrets.json file format, please visit: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets # Please ensure that you have enabled the YouTube Data API for your project. CLIENT_SECRETS_FILE = "client_secrets.json" # An OAuth 2 access scope that allows for full read/write access. YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" # Helpful 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 APIs 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)) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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 upload_banner(youtube, image_file): insert_request = youtube.channelBanners().insert( media_body = MediaFileUpload(image_file, chunksize=-1, resumable=True) ) image_url = resumable_upload(insert_request) set_banner(image_url) def resumable_upload(insert_request): response = None error = None retry = 0 while response is None: try: print "Uploading file..." status, response = insert_request.next_chunk() if 'url' in response: print "Banner was successfully uploaded to '%s'." % ( response['url']) else: exit("The upload failed with an unexpected response: %s" % response) except HttpError, e: if e.resp.status in RETRIABLE_STATUS_CODES: error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: raise except RETRIABLE_EXCEPTIONS, e: error = "A retriable error occurred: %s" % e if error is not None: print error retry += 1 if retry > MAX_RETRIES: exit("No longer attempting to retry.") max_sleep = 2 ** retry sleep_seconds = random.random() * max_sleep print "Sleeping %f seconds and then retrying..." % sleep_seconds time.sleep(sleep_seconds) return response['url'] def set_banner(banner_url): channels_response = youtube.channels().list( mine=True, part="brandingSettings" ).execute() if "brandingSettings" not in channels_response["items"][0]: channels_response["items"][0]["brandingSettings"]["image"]["bannerExternalUrl"] = [] channel_brandingSettings = channels_response["items"][0]["brandingSettings"] channel_brandingSettings["image"]["bannerExternalUrl"] = banner_url channels_update_response = youtube.channels().update( part='brandingSettings', body=dict( brandingSettings=channel_brandingSettings, id = channels_response["items"][0]["id"] )).execute() banner_mobile_url = channels_update_response["brandingSettings"]["image"]["bannerMobileImageUrl"] print "Banner is set to '%s'." % (banner_mobile_url) if __name__ == "__main__": argparser.add_argument("--file", required=True, help="Path to banner image file.") args = argparser.parse_args() if not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") youtube = get_authenticated_service(args) try: upload_banner(youtube, args.file) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "The custom banner was successfully uploaded."
Add a channel section
The following code sample calls the API's channelSections.insert
method to create channel sections. The code accepts a number of command line arguments that let you specify the section's type, display style, title, position, and content.
This sample also updates the channel's brandingSettings.channel.showBrowseView
property so that the channel displays content in a browse view (rather than a feed view). A channel's sections are only visible if the channel displays content in a browse view.
More information on channel sections is available in the YouTube Help Center.
#!/usr/bin/python import httplib2 import os import re 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account. YOUTUBE_SCOPE = "https://www.googleapis.com/auth/youtube" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" SECTION_TYPES = ("allPlaylists", "completedEvents", "likedPlaylists", "likes", "liveEvents", "multipleChannels", "multiplePlaylists", "popularUploads", "recentActivity", "recentPosts", "recentUploads", "singlePlaylist", "upcomingEvents",) SECTION_STYLES = ("horizontalRow", "verticalList",) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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 enable_browse_view(youtube): channels_list_response = youtube.channels().list( part="brandingSettings", mine=True ).execute() channel = channels_list_response["items"][0] channel["brandingSettings"]["channel"]["showBrowseView"] = True youtube.channels().update( part="brandingSettings", body=channel ).execute() def add_channel_section(youtube, args): channels = None if args.channels: channels = re.split("\s*,\s*", args.channels) playlists = None if args.playlists: playlists = re.split("\s*,\s*", args.playlists) body = dict( snippet=dict( type=args.type, style=args.style, title=args.title, position=args.position ), contentDetails=dict( channels=channels, playlists=playlists ) ) youtube.channelSections().insert( part="snippet,contentDetails", body=body ).execute() if __name__ == '__main__': argparser.add_argument("--type", choices=SECTION_TYPES, required=True, help="The type of the section to be added.") argparser.add_argument("--style", choices=SECTION_STYLES, required=True, help="The style of the section to be added.") argparser.add_argument("--title", help=("The title to display for the new section. This is only used " "with the multiplePlaylists or multipleChannels section types.")) argparser.add_argument("--position", type=int, help=("The position of the new section. " "Use 0 for the top, or don't set a value for the bottom.")) argparser.add_argument("--playlists", help="One or more playlist ids, comma-separated (e.g. PL...).") argparser.add_argument("--channels", help="One or more channel ids, comma-separated (e.g. UC...).") args = argparser.parse_args() youtube = get_authenticated_service(args) try: # Before channel shelves will appear on your channel's web page, browse # view needs to be enabled. If you know that your channel already has # it enabled, or if you want to add a number of sections before enabling it, # you can skip the call to enable_browse_view(). enable_browse_view(youtube) add_channel_section(youtube, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Added new channel section."
Shuffle existing channel sections
The following code sample calls the API's channelSections.list
method to get the list of current channel sections, shuffles them, and then calls channelSections.update
to change the position of each.
More information on channel sections is available in the YouTube Help Center.
#!/usr/bin/python import httplib2 import os import random 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account. YOUTUBE_SCOPE = "https://www.googleapis.com/auth/youtube" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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 get_current_channel_sections(youtube): channel_sections_list_response = youtube.channelSections().list( part="snippet,contentDetails", mine=True ).execute() return channel_sections_list_response["items"] def shuffle_channel_sections(youtube, channel_sections): # This will randomly reorder the items in the channel_sections list. random.shuffle(channel_sections) for channel_section in channel_sections: # Each section in the list of shuffled sections is sequentially # set to position 0, i.e. the top. channel_section["snippet"]["position"] = 0 youtube.channelSections().update( part="snippet,contentDetails", body=channel_section ).execute() if __name__ == '__main__': args = argparser.parse_args() youtube = get_authenticated_service(args) try: channel_sections = get_current_channel_sections(youtube) shuffle_channel_sections(youtube, channel_sections) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "The existing channel sections have been randomly shuffled."
Set and retrieve localized channel section metadata
The following code sample demonstrates how to use the following API methods to set and retrieve localized metadata for a channel section:
- It calls the
channelSections.update
method to update the default language of a channel section's metadata and to add a localized version of this metadata in a selected language. - It calls the
channelSections.list
method with thehl
parameter set to a specific language to retrieve localized metadata in that language. - It calls the
channelSections.list
method and includeslocalizations
in thepart
parameter value to retrieve all of the localized metadata for that channel section.
#!/usr/bin/python # Usage example: # python channel_sections_localizations.py --action='<action>' --channel_section_id='<channel_section_id>' --default_language='<default_language>' --language='<language>' --title='<title>' import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's channelSections.update method to update an existing channel section's # default language, and localized title in a specific language. def set_channel_section_localization(youtube, channel_section_id, default_language, language, title): results = youtube.channelSections().list( part="snippet,localizations", id=channel_section_id ).execute() channel_section = results["items"][0] # Ensure that a value is set for the resource's snippet.defaultLanguage property. channel_section["snippet"]["defaultLanguage"] = default_language if "localizations" not in channel_section: channel_section["localizations"] = {} channel_section["localizations"][language] = { "title": title } update_result = youtube.channelSections().update( part="snippet,localizations", body=channel_section ).execute() localization = update_result["localizations"][language] print ("Updated channel section '%s' default language to '%s', localized title" " to '%s' in language '%s'" % (channel_section_id, localization["title"], language)) # Call the API's channelSections.list method to retrieve an existing channel section localization. # If the localized text is not available in the requested language, # this method will return text in the default language. def get_channel_section_localization(youtube, channel_section_id, language): results = youtube.channelSections().list( part="snippet", id=channel_section_id, hl=language ).execute() # The localized object contains localized text if the hl parameter specified # a language for which localized text is available. Otherwise, the localized # object will contain metadata in the default language. localized = results["items"][0]["snippet"]["localized"] print "Channel section title is '%s' in language '%s'" % (localized["title"], language) # Call the API's channelSections.list method to list the existing channel section localizations. def list_channel_section_localizations(youtube, channel_section_id): results = youtube.channelSections().list( part="snippet,localizations", id=channel_section_id ).execute() localizations = results["items"][0]["localizations"] for language, localization in localizations.iteritems(): print "Channel section title is '%s' in language '%s'" % (localization["title"], language) if __name__ == "__main__": # The "action" option specifies the action to be processed. argparser.add_argument("--action", help="Action") # The "channel_section_id" option specifies the ID of the selected YouTube channel section. argparser.add_argument("--channel_section_id", help="ID for channel section for which the localization will be applied.") # The "default_language" option specifies the language of the channel section's default metadata. argparser.add_argument("--default_language", help="Default language of the channel section to update.", default="en") # The "language" option specifies the language of the localization that is being processed. argparser.add_argument("--language", help="Language of the localization.", default="de") # The "title" option specifies the localized title of the channel section to be set. argparser.add_argument("--title", help="Localized title of the channel section to be set.", default="Localized Title") args = argparser.parse_args() if not args.channel_section_id: exit("Please specify channel section id using the --channel_section_id= parameter.") youtube = get_authenticated_service(args) try: if args.action == 'set': set_channel_section_localization(youtube, args.channel_section_id, args.default_language, args.language, args.title) elif args.action == 'get': get_channel_section_localization(youtube, args.channel_section_id, args.language) elif args.action == 'list': list_channel_section_localizations(youtube, args.channel_section_id) else: exit("Please specify a valid action using the --action= parameter.") except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Set and retrieved localized metadata for a channel section."
Add a featured video
The following code sample calls the API's channels.update
method to set invideoPromotion
properties for the channel.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account. YOUTUBE_SCOPE = "https://www.googleapis.com/auth/youtube" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" # If offsetMs is not valid, the API will throw an error VALID_OFFSET_TYPES = ("offsetFromEnd", "offsetFromStart",) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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 add_featured_video(youtube, options): add_video_request = youtube.channels().update( part="invideoPromotion", # You can use the API Explorer to test API requests: # https://developers.google.com/youtube/v3/docs/channels/update#try-it body={ "invideoPromotion": { "items": [{ "id": { "type": "video", "videoId": options.video_id }, "timing": { "offsetMs": options.offset_ms, "type": options.offset_type } }], }, "id": options.channel_id }).execute() if __name__ == '__main__': argparser.add_argument("--channel-id", required=True, help="Channel ID of the channel to add a featured video") argparser.add_argument("--video-id", required=True, help="Video ID to feature on your channel") argparser.add_argument("--offset-ms", help="Offset in milliseconds to show video.", default="10000") argparser.add_argument("--offset-type", choices=VALID_OFFSET_TYPES, help="Whether the offset is from the beginning or end of video playback.", default=VALID_OFFSET_TYPES[0]) args = argparser.parse_args() youtube = get_authenticated_service(args) try: add_featured_video(youtube, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Added featured video %s to channel %s." % ( args.video_id, args.channel_id)
Set and retrieve localized channel metadata
The following code sample demonstrates how to use the following API methods to set and retrieve localized metadata for a channel:
- It calls the
channels.update
method to update the default language of a channel's metadata and to add a localized version of this metadata in a selected language. Note that to set the default language for a channel resource, you actually need to update thebrandingSettings.channel.defaultLanguage
property. - It calls the
channels.list
method with thehl
parameter set to a specific language to retrieve localized metadata in that language. - It calls the
channels.list
method and includeslocalizations
in thepart
parameter value to retrieve all of the localized metadata for that channel.
#!/usr/bin/python # Usage example: # python channel_localizations.py --action='<action>' --channel_id='<channel_id>' --default_language='<default_language>' --language='<language>' --description='<description>' import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's channels.update method to update an existing channel's default language, # and localized description in a specific language. def set_channel_localization(youtube, channel_id, default_language, language, description): results = youtube.channels().list( part="brandingSettings,localizations", id=channel_id ).execute() channel = results["items"][0] # Ensure that a value is set for the resource's snippet.defaultLanguage property. # To set the snippet.defaultLanguage property for a channel resource, # you actually need to update the brandingSettings.channel.defaultLanguage property. channel["brandingSettings"]["channel"]["defaultLanguage"] = default_language if "localizations" not in channel: channel["localizations"] = {} channel["localizations"][language] = { "description": description } update_result = youtube.channels().update( part="brandingSettings,localizations", body=channel ).execute() localization = update_result["localizations"][language] print ("Updated channel '%s' default language to '%s', localized description" " to '%s' in language '%s'" % (channel_id, localization["description"], language)) # Call the API's channels.list method to retrieve an existing channel localization. # If the localized text is not available in the requested language, # this method will return text in the default language. def get_channel_localization(youtube, channel_id, language): results = youtube.channels().list( part="snippet", id=channel_id, hl=language ).execute() # The localized object contains localized text if the hl parameter specified # a language for which localized text is available. Otherwise, the localized # object will contain metadata in the default language. localized = results["items"][0]["snippet"]["localized"] print "Channel description is '%s' in language '%s'" % (localized["description"], language) # Call the API's channels.list method to list the existing channel localizations. def list_channel_localizations(youtube, channel_id): results = youtube.channels().list( part="snippet,localizations", id=channel_id ).execute() localizations = results["items"][0]["localizations"] for language, localization in localizations.iteritems(): print "Channel description is '%s' in language '%s'" % (localization["description"], language) if __name__ == "__main__": # The "action" option specifies the action to be processed. argparser.add_argument("--action", help="Action") # The "channel_id" option specifies the ID of the selected YouTube channel. argparser.add_argument("--channel_id", help="ID for channel for which the localization will be applied.") # The "default_language" option specifies the language of the channel's default metadata. argparser.add_argument("--default_language", help="Default language of the channel to update.", default="en") # The "language" option specifies the language of the localization that is being processed. argparser.add_argument("--language", help="Language of the localization.", default="de") # The "description" option specifies the localized description of the chanel to be set. argparser.add_argument("--description", help="Localized description of the channel to be set.", default="Localized Description") args = argparser.parse_args() if not args.channel_id: exit("Please specify channel id using the --channel_id= parameter.") youtube = get_authenticated_service(args) try: if args.action == 'set': set_channel_localization(youtube, args.channel_id, args.default_language, args.language, args.description) elif args.action == 'get': get_channel_localization(youtube, args.channel_id, args.language) elif args.action == 'list': list_channel_localizations(youtube, args.channel_id) else: exit("Please specify a valid action using the --action= parameter.") except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Set and retrieved localized metadata for a channel."
Create and manage top-level comments
The following code sample demonstrates how to use the following API methods to create and manage top-level comments:
- It calls the
commentThreads.insert
method once with thechannelId
parameter to create a channel comment and once with thevideoId
parameter to create a video comment. - It calls the
commentThreads.list
method once with thechannelId
parameter to retrieve channel comments and once with thevideoId
parameter to retrieve video comments. - It calls the
commentThreads.update
method once to update a video comment and then again to update a channel comment. In each case, the request body contains thecomment
resource being updated.
#!/usr/bin/python # Usage example: # python comment_threads.py --channelid='<channel_id>' --videoid='<video_id>' --text='<text>' import httplib2 import os import sys from apiclient.discovery import build_from_document from apiclient.errors import HttpError from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl" 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: credentials = run_flow(flow, storage, args) # Trusted testers can download this discovery document from the developers page # and it should be in the same directory with the code. with open("youtube-v3-discoverydocument.json", "r") as f: doc = f.read() return build_from_document(doc, http=credentials.authorize(httplib2.Http())) # Call the API's commentThreads.list method to list the existing comments. def get_comments(youtube, video_id, channel_id): results = youtube.commentThreads().list( part="snippet", videoId=video_id, channelId=channel_id, textFormat="plainText" ).execute() for item in results["items"]: comment = item["snippet"]["topLevelComment"] author = comment["snippet"]["authorDisplayName"] text = comment["snippet"]["textDisplay"] print "Comment by %s: %s" % (author, text) return results["items"] # Call the API's commentThreads.insert method to insert a comment. def insert_comment(youtube, channel_id, video_id, text): insert_result = youtube.commentThreads().insert( part="snippet", body=dict( snippet=dict( channelId=channel_id, videoId=video_id, topLevelComment=dict( snippet=dict( textOriginal=text ) ) ) ) ).execute() comment = insert_result["snippet"]["topLevelComment"] author = comment["snippet"]["authorDisplayName"] text = comment["snippet"]["textDisplay"] print "Inserted comment for %s: %s" % (author, text) # Call the API's commentThreads.update method to update an existing comment. def update_comment(youtube, comment): comment["snippet"]["topLevelComment"]["snippet"]["textOriginal"] = 'updated' update_result = youtube.commentThreads().update( part="snippet", body=comment ).execute() comment = update_result["snippet"]["topLevelComment"] author = comment["snippet"]["authorDisplayName"] text = comment["snippet"]["textDisplay"] print "Updated comment for %s: %s" % (author, text) if __name__ == "__main__": # The "channelid" option specifies the YouTube channel ID that uniquely # identifies the channel for which the comment will be inserted. argparser.add_argument("--channelid", help="Required; ID for channel for which the comment will be inserted.") # The "videoid" option specifies the YouTube video ID that uniquely # identifies the video for which the comment will be inserted. argparser.add_argument("--videoid", help="Required; ID for video for which the comment will be inserted.") # The "text" option specifies the text that will be used as comment. argparser.add_argument("--text", help="Required; text that will be used as comment.") args = argparser.parse_args() if not args.channelid: exit("Please specify channelid using the --channelid= parameter.") if not args.videoid: exit("Please specify videoid using the --videoid= parameter.") if not args.text: exit("Please specify text using the --text= parameter.") youtube = get_authenticated_service(args) try: # All the available methods are used in sequence just for the sake of an example. # Insert channel comment by omitting videoId insert_comment(youtube, args.channelid, None, args.text) # Insert video comment insert_comment(youtube, args.channelid, args.videoid, args.text) video_comments = get_comments(youtube, args.videoid, None) if video_comments: update_comment(youtube, video_comments[0]) channel_comments = get_comments(youtube, None, args.channelid) if channel_comments: update_comment(youtube, channel_comments[0]) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Inserted, listed and updated top-level comments."
Create and manage comments
The following code sample demonstrates how to use the following API methods to create and manage comments:
- It calls the
commentThreads.list
method with thevideoId
parameter set to retrieve comments for a video. - It calls the
comments.insert
method with theparentId
parameter set to reply to an existing comment. - It calls the
comments.list
method with theparentId
parameter to retrieve the comments in the thread. - It calls the
comments.update
method with comment in the request body to update a comment. - It calls the
comments.setModerationStatus
method to set the moderation status of the comment, thecomments.markAsSpam
method to mark the comment as spam, and thecomments.delete
method to delete the comment, using theid
parameter to identify the comment.
#!/usr/bin/python # Usage example: # python comments.py --videoid='<video_id>' --text='<text>' import httplib2 import os import sys from apiclient.discovery import build_from_document from apiclient.errors import HttpError from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. YOUTUBE_READ_WRITE_SSL_SCOPE = "https://www.googleapis.com/auth/youtube.force-ssl" 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SSL_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: credentials = run_flow(flow, storage, args) # Trusted testers can download this discovery document from the developers page # and it should be in the same directory with the code. with open("youtube-v3-discoverydocument.json", "r") as f: doc = f.read() return build_from_document(doc, http=credentials.authorize(httplib2.Http())) # Call the API's commentThreads.list method to list the existing comment threads. def get_comment_threads(youtube, video_id): results = youtube.commentThreads().list( part="snippet", videoId=video_id, textFormat="plainText" ).execute() for item in results["items"]: comment = item["snippet"]["topLevelComment"] author = comment["snippet"]["authorDisplayName"] text = comment["snippet"]["textDisplay"] print "Comment by %s: %s" % (author, text) return results["items"] # Call the API's comments.list method to list the existing comment replies. def get_comments(youtube, parent_id): results = youtube.comments().list( part="snippet", parentId=parent_id, textFormat="plainText" ).execute() for item in results["items"]: author = item["snippet"]["authorDisplayName"] text = item["snippet"]["textDisplay"] print "Comment by %s: %s" % (author, text) return results["items"] # Call the API's comments.insert method to reply to a comment. # (If the intention is to create a new to-level comment, commentThreads.insert # method should be used instead.) def insert_comment(youtube, parent_id, text): insert_result = youtube.comments().insert( part="snippet", body=dict( snippet=dict( parentId=parent_id, textOriginal=text ) ) ).execute() author = insert_result["snippet"]["authorDisplayName"] text = insert_result["snippet"]["textDisplay"] print "Replied to a comment for %s: %s" % (author, text) # Call the API's comments.update method to update an existing comment. def update_comment(youtube, comment): comment["snippet"]["textOriginal"] = 'updated' update_result = youtube.comments().update( part="snippet", body=comment ).execute() author = update_result["snippet"]["authorDisplayName"] text = update_result["snippet"]["textDisplay"] print "Updated comment for %s: %s" % (author, text) # Call the API's comments.setModerationStatus method to set moderation status of an # existing comment. def set_moderation_status(youtube, comment): youtube.comments().setModerationStatus( id=comment["id"], moderationStatus="published" ).execute() print "%s moderated succesfully" % (comment["id"]) # Call the API's comments.markAsSpam method to mark an existing comment as spam. def mark_as_spam(youtube, comment): youtube.comments().markAsSpam( id=comment["id"] ).execute() print "%s marked as spam succesfully" % (comment["id"]) # Call the API's comments.delete method to delete an existing comment. def delete_comment(youtube, comment): youtube.comments().delete( id=comment["id"] ).execute() print "%s deleted succesfully" % (comment["id"]) if __name__ == "__main__": # The "videoid" option specifies the YouTube video ID that uniquely # identifies the video for which the comment will be inserted. argparser.add_argument("--videoid", help="Required; ID for video for which the comment will be inserted.") # The "text" option specifies the text that will be used as comment. argparser.add_argument("--text", help="Required; text that will be used as comment.") args = argparser.parse_args() if not args.videoid: exit("Please specify videoid using the --videoid= parameter.") if not args.text: exit("Please specify text using the --text= parameter.") youtube = get_authenticated_service(args) # All the available methods are used in sequence just for the sake of an example. try: video_comment_threads = get_comment_threads(youtube, args.videoid) parent_id = video_comment_threads[0]["id"] insert_comment(youtube, parent_id, args.text) video_comments = get_comments(youtube, parent_id) update_comment(youtube, video_comments[0]) set_moderation_status(youtube, video_comments[0]) mark_as_spam(youtube, video_comments[0]) delete_comment(youtube, video_comments[0]) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Inserted, listed, updated, moderated, marked and deleted comments."
Retrieve my uploads
The following code sample calls the API's playlistItems.list
method to retrieve a list of videos uploaded to the channel associated with the request. The code also calls the channels.list
method with the mine
parameter set to true
to retrieve the playlist ID that identifies the channel's uploaded videos.
#!/usr/bin/python import httplib2 import os import sys from apiclient.discovery import build from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) # This OAuth 2.0 access scope allows for read-only access to the authenticated # user's account, but not other types of account access. YOUTUBE_READONLY_SCOPE = "https://www.googleapis.com/auth/youtube.readonly" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, message=MISSING_CLIENT_SECRETS_MESSAGE, scope=YOUTUBE_READONLY_SCOPE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: flags = argparser.parse_args() credentials = run_flow(flow, storage, flags) youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http())) # Retrieve the contentDetails part of the channel resource for the # authenticated user's channel. channels_response = youtube.channels().list( mine=True, part="contentDetails" ).execute() for channel in channels_response["items"]: # From the API response, extract the playlist ID that identifies the list # of videos uploaded to the authenticated user's channel. uploads_list_id = channel["contentDetails"]["relatedPlaylists"]["uploads"] print "Videos in list %s" % uploads_list_id # Retrieve the list of videos uploaded to the authenticated user's channel. playlistitems_list_request = youtube.playlistItems().list( playlistId=uploads_list_id, part="snippet", maxResults=50 ) while playlistitems_list_request: playlistitems_list_response = playlistitems_list_request.execute() # Print information about each video. for playlist_item in playlistitems_list_response["items"]: title = playlist_item["snippet"]["title"] video_id = playlist_item["snippet"]["resourceId"]["videoId"] print "%s (%s)" % (title, video_id) playlistitems_list_request = youtube.playlistItems().list_next( playlistitems_list_request, playlistitems_list_response) print
Create a playlist
The following code sample calls the API's playlists.insert
method to create a private playlist owned by the channel authorizing the request.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) # 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" flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, message=MISSING_CLIENT_SECRETS_MESSAGE, scope=YOUTUBE_READ_WRITE_SCOPE) storage = Storage("%s-oauth2.json" % sys.argv[0]) credentials = storage.get() if credentials is None or credentials.invalid: flags = argparser.parse_args() credentials = run_flow(flow, storage, flags) youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=credentials.authorize(httplib2.Http())) # This code creates a new, private playlist in the authorized user's channel. playlists_insert_response = youtube.playlists().insert( part="snippet,status", body=dict( snippet=dict( title="Test Playlist", description="A private playlist created with the YouTube API v3" ), status=dict( privacyStatus="private" ) ) ).execute() print "New playlist id: %s" % playlists_insert_response["id"]
Set and retrieve localized playlist metadata
The following code sample demonstrates how to use the following API methods to set and retrieve localized metadata for a playlist:
- It calls the
playlists.update
method to update the default language of a playlist's metadata and to add a localized version of this metadata in a selected language. - It calls the
playlists.list
method with thehl
parameter set to a specific language to retrieve localized metadata in that language. - It calls the
playlists.list
method and includeslocalizations
in thepart
parameter value to retrieve all of the localized metadata for that playlist.
#!/usr/bin/python # Usage example: # python playlist_localizations.py --action='<action>' --playlist_id='<playlist_id>' --defaultlanguage='<default_language>' --language='<language>' --title='<title>' --description='<description>' import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's playlists.update method to update an existing playlist's default language, # localized title and description in a specific language. def set_playlist_localization(youtube, playlist_id, default_language, language, title, description): results = youtube.playlists().list( part="snippet,localizations", id=playlist_id ).execute() playlist = results["items"][0] # Ensure that a value is set for the resource's snippet.defaultLanguage property. playlist["snippet"]["defaultLanguage"] = default_language if "localizations" not in playlist: playlist["localizations"] = {} playlist["localizations"][language] = { "title": title, "description": description } update_result = youtube.playlists().update( part="snippet,localizations", body=playlist ).execute() localization = update_result["localizations"][language] print ("Updated playlist '%s' default language to '%s', localized title to '%s'" " and description to '%s' in language '%s'" % (playlist_id, localization["title"], localization["description"], language)) # Call the API's playlists.list method to retrieve an existing playlist localization. # If the localized text is not available in the requested language, # this method will return text in the default language. def get_playlist_localization(youtube, playlist_id, language): results = youtube.playlists().list( part="snippet", id=playlist_id, hl=language ).execute() # The localized object contains localized text if the hl parameter specified # a language for which localized text is available. Otherwise, the localized # object will contain metadata in the default language. localized = results["items"][0]["snippet"]["localized"] print ("Playlist title is '%s' and description is '%s' in language '%s'" % (localized["title"], localized["description"], language)) # Call the API's playlists.list method to list the existing playlist localizations. def list_playlist_localizations(youtube, playlist_id): results = youtube.playlists().list( part="snippet,localizations", id=playlist_id ).execute() localizations = results["items"][0]["localizations"] for language, localization in localizations.iteritems(): print ("Playlist title is '%s' and description is '%s' in language '%s'" % (localization["title"], localization["description"], language)) if __name__ == "__main__": # The "action" option specifies the action to be processed. argparser.add_argument("--action", help="Action") # The "playlist_id" option specifies the ID of the selected YouTube playlist. argparser.add_argument("--playlist_id", help="ID for playlist for which the localization will be applied.") # The "default_language" option specifies the language of the playlist's default metadata. argparser.add_argument("--default_language", help="Default language of the playlist to update.", default="en") # The "language" option specifies the language of the localization that is being processed. argparser.add_argument("--language", help="Language of the localization.", default="de") # The "title" option specifies the localized title of the playlist to be set. argparser.add_argument("--title", help="Localized title of the playlist to be set.", default="Localized Title") # The "description" option specifies the localized description of the playlist to be set. argparser.add_argument("--description", help="Localized description of the playlist to be set.", default="Localized Description") args = argparser.parse_args() if not args.playlist_id: exit("Please specify playlist id using the --playlist_id= parameter.") youtube = get_authenticated_service(args) try: if args.action == 'set': set_playlist_localization(youtube, args.playlist_id, args.default_language, args.language, args.title, args.description) elif args.action == 'get': get_playlist_localization(youtube, args.playlist_id, args.language) elif args.action == 'list': list_playlist_localizations(youtube, args.playlist_id) else: exit("Please specify a valid action using the --action= parameter.") except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Set and retrieved localized metadata for a playlist."
Search by keyword
The following code sample calls the API's search.list
method to retrieve search results associated with a particular keyword.
#!/usr/bin/python from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.tools import argparser # Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps # tab of # https://cloud.google.com/console # Please ensure that you have enabled the YouTube Data API for your project. DEVELOPER_KEY = "REPLACE_ME" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" def youtube_search(options): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY) # Call the search.list method to retrieve results matching the specified # query term. search_response = youtube.search().list( q=options.q, part="id,snippet", maxResults=options.max_results ).execute() videos = [] channels = [] playlists = [] # Add each result to the appropriate list, and then display the lists of # matching videos, channels, and playlists. for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": videos.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["videoId"])) elif search_result["id"]["kind"] == "youtube#channel": channels.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["channelId"])) elif search_result["id"]["kind"] == "youtube#playlist": playlists.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["playlistId"])) print "Videos:\n", "\n".join(videos), "\n" print "Channels:\n", "\n".join(channels), "\n" print "Playlists:\n", "\n".join(playlists), "\n" if __name__ == "__main__": argparser.add_argument("--q", help="Search term", default="Google") argparser.add_argument("--max-results", help="Max results", default=25) args = argparser.parse_args() try: youtube_search(args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
Search by topic
The following code sample calls the API's search.list
method to retrieve search results associated with a particular Freebase topic.
#!/usr/bin/python from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.tools import argparser import json import urllib # Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps # tab of # https://cloud.google.com/console # Please ensure that you have enabled the YouTube Data API for your project. DEVELOPER_KEY = "REPLACE_ME" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" FREEBASE_SEARCH_URL = "https://www.googleapis.com/freebase/v1/search?%s" def get_topic_id(options): # Retrieve a list of Freebase topics associated with the provided query term. freebase_params = dict(query=options.query, key=DEVELOPER_KEY) freebase_url = FREEBASE_SEARCH_URL % urllib.urlencode(freebase_params) freebase_response = json.loads(urllib.urlopen(freebase_url).read()) if len(freebase_response["result"]) == 0: exit("No matching terms were found in Freebase.") # Display the list of matching Freebase topics. mids = [] index = 1 print "The following topics were found:" for result in freebase_response["result"]: mids.append(result["mid"]) print " %2d. %s (%s)" % (index, result.get("name", "Unknown"), result.get("notable", {}).get("name", "Unknown")) index += 1 # Display a prompt for the user to select a topic and return the topic ID # of the selected topic. mid = None while mid is None: index = raw_input("Enter a topic number to find related YouTube %ss: " % options.type) try: mid = mids[int(index) - 1] except ValueError: pass return mid def youtube_search(mid, options): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY) # Call the search.list method to retrieve results associated with the # specified Freebase topic. search_response = youtube.search().list( topicId=mid, type=options.type, part="id,snippet", maxResults=options.max_results ).execute() # Print the title and ID of each matching resource. for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": print "%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["videoId"]) elif search_result["id"]["kind"] == "youtube#channel": print "%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["channelId"]) elif search_result["id"]["kind"] == "youtube#playlist": print "%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["playlistId"]) if __name__ == "__main__": argparser.add_argument("--query", help="Freebase search term", default="Google") argparser.add_argument("--max-results", help="Max YouTube results", default=25) argparser.add_argument("--type", help="YouTube result type: video, playlist, or channel", default="channel") args = argparser.parse_args() mid = get_topic_id(args) try: youtube_search(mid, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
Search by geolocation
The following code sample calls the API's search.list
method with q
, location
and locationRadius
parameters to retrieve search results matching the provided keyword within the radius centered at a particular location. Using the video ids from the search result, the sample calls the API's videos.list
method to retrieve location details of each video.
#!/usr/bin/python from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.tools import argparser # Set DEVELOPER_KEY to the API key value from the APIs & auth > Registered apps # tab of # https://cloud.google.com/console # Please ensure that you have enabled the YouTube Data API for your project. DEVELOPER_KEY = "REPLACE_ME" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" def youtube_search(options): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY) # Call the search.list method to retrieve results matching the specified # query term. search_response = youtube.search().list( q=options.q, type="video", location=options.location, locationRadius=options.location_radius, part="id,snippet", maxResults=options.max_results ).execute() search_videos = [] # Merge video ids for search_result in search_response.get("items", []): search_videos.append(search_result["id"]["videoId"]) video_ids = ",".join(search_videos) # Call the videos.list method to retrieve location details for each video. video_response = youtube.videos().list( id=video_ids, part='snippet, recordingDetails' ).execute() videos = [] # Add each result to the list, and then display the list of matching videos. for video_result in video_response.get("items", []): videos.append("%s, (%s,%s)" % (video_result["snippet"]["title"], video_result["recordingDetails"]["location"]["latitude"], video_result["recordingDetails"]["location"]["longitude"])) print "Videos:\n", "\n".join(videos), "\n" if __name__ == "__main__": argparser.add_argument("--q", help="Search term", default="Google") argparser.add_argument("--location", help="Location", default="37.42307,-122.08427") argparser.add_argument("--location-radius", help="Location radius", default="5km") argparser.add_argument("--max-results", help="Max results", default=25) args = argparser.parse_args() try: youtube_search(args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
Add a channel subscription
The following code sample calls the API's subscriptions.insert
method to add a subscription to a specified channel.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # This method calls the API's youtube.subscriptions.insert method to add a # subscription to the specified channel. def add_subscription(youtube, channel_id): add_subscription_response = youtube.subscriptions().insert( part='snippet', body=dict( snippet=dict( resourceId=dict( channelId=channel_id ) ) )).execute() return add_subscription_response["snippet"]["title"] if __name__ == "__main__": argparser.add_argument("--channel-id", help="ID of the channel to subscribe to.", default="UCtVd0c0tGXuTSbU5d8cSBUg") args = argparser.parse_args() youtube = get_authenticated_service(args) try: channel_title = add_subscription(youtube, args.channel_id) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "A subscription to '%s' was added." % channel_title
Upload a video thumbnail image
The following code sample calls the API's thumbnails.set
method to upload an image and set it as the thumbnail image for a video. The request must be authorized by the channel that owns the video.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's thumbnails.set method to upload the thumbnail image and # associate it with the appropriate video. def upload_thumbnail(youtube, video_id, file): youtube.thumbnails().set( videoId=video_id, media_body=file ).execute() if __name__ == "__main__": # The "videoid" option specifies the YouTube video ID that uniquely # identifies the video for which the thumbnail image is being updated. argparser.add_argument("--video-id", required=True, help="ID of video whose thumbnail you're updating.") # The "file" option specifies the path to the thumbnail image file. argparser.add_argument("--file", required=True, help="Path to thumbnail image file.") args = argparser.parse_args() if not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") youtube = get_authenticated_service(args) try: upload_thumbnail(youtube, args.video_id, args.file) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "The custom thumbnail was successfully set."
Upload a video
The following code sample calls the API's videos.insert
method to upload a video to the channel associated with the request.
#!/usr/bin/python import httplib import httplib2 import os import random import sys import time from apiclient.discovery import build from apiclient.errors import HttpError from apiclient.http import MediaFileUpload from oauth2client.client import flow_from_clientsecrets from oauth2client.file import Storage from oauth2client.tools import argparser, run_flow # Explicitly tell the underlying HTTP transport library not to retry, since # we are handling retry logic ourselves. httplib2.RETRIES = 1 # Maximum number of times to retry before giving up. MAX_RETRIES = 10 # Always retry when these exceptions are raised. RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected, httplib.IncompleteRead, httplib.ImproperConnectionState, httplib.CannotSendRequest, httplib.CannotSendHeader, httplib.ResponseNotReady, httplib.BadStatusLine) # Always retry when an apiclient.errors.HttpError with one of these status # codes is raised. RETRIABLE_STATUS_CODES = [500, 502, 503, 504] # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # This OAuth 2.0 access scope allows an application to upload files to the # authenticated user's YouTube channel, but doesn't allow other types of access. YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload" 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 Developers Console https://console.developers.google.com/ 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)) VALID_PRIVACY_STATUSES = ("public", "private", "unlisted") def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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 initialize_upload(youtube, options): tags = None if options.keywords: tags = options.keywords.split(",") body=dict( snippet=dict( title=options.title, description=options.description, tags=tags, categoryId=options.category ), status=dict( privacyStatus=options.privacyStatus ) ) # Call the API's videos.insert method to create and upload the video. insert_request = youtube.videos().insert( part=",".join(body.keys()), body=body, # The chunksize parameter specifies the size of each chunk of data, in # bytes, that will be uploaded at a time. Set a higher value for # reliable connections as fewer chunks lead to faster uploads. Set a lower # value for better recovery on less reliable connections. # # Setting "chunksize" equal to -1 in the code below means that the entire # file will be uploaded in a single HTTP request. (If the upload fails, # it will still be retried where it left off.) This is usually a best # practice, but if you're using Python older than 2.6 or if you're # running on App Engine, you should set the chunksize to something like # 1024 * 1024 (1 megabyte). media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True) ) resumable_upload(insert_request) # This method implements an exponential backoff strategy to resume a # failed upload. def resumable_upload(insert_request): response = None error = None retry = 0 while response is None: try: print "Uploading file..." status, response = insert_request.next_chunk() if response is not None: if 'id' in response: print "Video id '%s' was successfully uploaded." % response['id'] else: exit("The upload failed with an unexpected response: %s" % response) except HttpError, e: if e.resp.status in RETRIABLE_STATUS_CODES: error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: raise except RETRIABLE_EXCEPTIONS, e: error = "A retriable error occurred: %s" % e if error is not None: print error retry += 1 if retry > MAX_RETRIES: exit("No longer attempting to retry.") max_sleep = 2 ** retry sleep_seconds = random.random() * max_sleep print "Sleeping %f seconds and then retrying..." % sleep_seconds time.sleep(sleep_seconds) if __name__ == '__main__': argparser.add_argument("--file", required=True, help="Video file to upload") argparser.add_argument("--title", help="Video title", default="Test Title") argparser.add_argument("--description", help="Video description", default="Test Description") argparser.add_argument("--category", default="22", help="Numeric video category. " + "See https://developers.google.com/youtube/v3/docs/videoCategories/list") argparser.add_argument("--keywords", help="Video keywords, comma separated", default="") argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES, default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.") args = argparser.parse_args() if not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") youtube = get_authenticated_service(args) try: initialize_upload(youtube, args) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
Rate (like) a video
The following code sample calls the API's videos.rate
method to set a positive rating for a video.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) # 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" def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Add the video rating. This code sets the rating to "like," but you could # also support an additional option that supports values of "like" and # "dislike." def like_video(youtube, video_id): youtube.videos().rate( id=video_id, rating="like" ).execute() if __name__ == "__main__": argparser.add_argument("--videoid", default="L-oNKK1CrnU", help="ID of video to like.") args = argparser.parse_args() youtube = get_authenticated_service(args) try: like_video(youtube, args.videoid) except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "%s has been liked." % args.videoid
Update a video
The following code sample calls the API's videos.update
method to update a video owned by the channel authorizing the request.
#!/usr/bin/python import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com/ 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)) def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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): # Call the API's videos.list method to retrieve the video resource. videos_list_response = youtube.videos().list( id=options.video_id, part='snippet' ).execute() # 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 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"] # 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) # 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 )).execute() if __name__ == "__main__": argparser.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) 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)
Set and retrieve localized video metadata
The following code sample demonstrates how to use the following API methods to set and retrieve localized metadata for a video:
- It calls the
videos.update
method to update the default language of a video's metadata and to add a localized version of this metadata in a selected language. - It calls the
videos.list
method with thehl
parameter set to a specific language to retrieve localized metadata in that language. - It calls the
videos.list
method and includeslocalizations
in thepart
parameter value to retrieve all of the localized metadata for that video.
#!/usr/bin/python # Usage example: # python video_localizations.py --action='<action>' --video_id='<video_id>' --default_language='<default_language>' --language='<language>' --title='<title>' --description='<description>' import httplib2 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 # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 APIs Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's videos.update method to update an existing video's default language, # localized title and description in a specific language. def set_video_localization(youtube, video_id, default_language, language, title, description): results = youtube.videos().list( part="snippet,localizations", id=video_id ).execute() video = results["items"][0] # Ensure that a value is set for the resource's snippet.defaultLanguage property. video["snippet"]["defaultLanguage"] = default_language if "localizations" not in video: video["localizations"] = {} video["localizations"][language] = { "title": title, "description": description } update_result = youtube.videos().update( part="snippet,localizations", body=video ).execute() localization = update_result["localizations"][language] print ("Updated video '%s' default language to '%s', localized title to '%s'" " and description to '%s' in language '%s'" % (video_id, default_language, localization["title"], localization["description"], language)) # Call the API's videos.list method to retrieve an existing video localization. # If the localized text is not available in the requested language, # this method will return text in the default language. def get_video_localization(youtube, video_id, language): results = youtube.videos().list( part="snippet", id=video_id, hl=language ).execute() # The localized object contains localized text if the hl parameter specified # a language for which localized text is available. Otherwise, the localized # object will contain metadata in the default language. localized = results["items"][0]["snippet"]["localized"] print ("Video title is '%s' and description is '%s' in language '%s'" % (localized["title"], localized["description"], language)) # Call the API's videos.list method to list the existing video localizations. def list_video_localizations(youtube, video_id): results = youtube.videos().list( part="snippet,localizations", id=video_id ).execute() localizations = results["items"][0]["localizations"] for language, localization in localizations.iteritems(): print ("Video title is '%s' and description is '%s' in language '%s'" % (localization["title"], localization["description"], language)) if __name__ == "__main__": # The "action" option specifies the action to be processed. argparser.add_argument("--action", help="Action") # The "video_id" option specifies the ID of the selected YouTube video. argparser.add_argument("--video_id", help="ID for video for which the localization will be applied.") # The "default_language" option specifies the language of the video's default metadata. argparser.add_argument("--default_language", help="Default language of the video to update.", default="en") # The "language" option specifies the language of the localization that is being processed. argparser.add_argument("--language", help="Language of the localization.", default="de") # The "title" option specifies the localized title of the video to be set. argparser.add_argument("--title", help="Localized title of the video to be set.", default="Localized Title") # The "description" option specifies the localized description of the video to be set. argparser.add_argument("--description", help="Localized description of the video to be set.", default="Localized Description") args = argparser.parse_args() if not args.video_id: exit("Please specify video id using the --video_id= parameter.") youtube = get_authenticated_service(args) try: if args.action == 'set': set_video_localization(youtube, args.video_id, args.default_language, args.language, args.title, args.description) elif args.action == 'get': get_video_localization(youtube, args.video_id, args.language) elif args.action == 'list': list_video_localizations(youtube, args.video_id) else: exit("Please specify a valid action using the --action= parameter.") except HttpError, e: print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: print "Set and retrieved localized metadata for a video."
Upload a watermark image and set it for a channel
The following code sample calls the API's watermarks.set
method to upload an image and set it as the watermark image for a channel. The request must be authorized by the channel that owns the video.
#!/usr/bin/python # Usage example: # python set_watermark.py --channelid='<channel_id>' --file='<file_name>' # --metadata='{ "position": { "type": "corner", "cornerPosition": "topRight" }, # "timing": { "type": "offsetFromStart", "offsetMs": 42 } }' import json import os import sys import httplib2 from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.file import Storage from oauth2client.client import flow_from_clientsecrets from oauth2client.tools import argparser, run_flow # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the Google Developers Console at # https://console.developers.google.com/project/_/apiui/credential # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: # 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" # 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 Developers Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's watermarks.set method to upload the watermark image and # associate it with the proper channel. def set_watermark(youtube, channel_id, file, metadata): try: youtube.watermarks().set( channelId=channel_id, media_body=file, body=metadata, ).execute() except HttpError as e: print "Error while setting watermark: %s" % e.content raise e if __name__ == "__main__": # The "channelid" option specifies the YouTube channel ID that uniquely # identifies the channel for which the watermark image is being updated. argparser.add_argument("--channelid", dest="channelid", help="Required; ID for channel that is having its watermark updated.") # The "file" option specifies the path to the image being uploaded. argparser.add_argument("--file", dest="file", help="Required; path to watermark image file.") # The "metadata" option specifies the JSON for the watermark resource # provided with the request. argparser.add_argument("--metadata", dest="metadata", help="Required; watermark metadata in JSON format.") args = argparser.parse_args() if not args.channelid: argparser.print_help() exit() youtube = get_authenticated_service(args) if not args.file or not os.path.exists(args.file): exit("Please specify a valid file using the --file= parameter.") if not args.metadata: exit("Please specify watermark metadata using the --metadata= parameter.") set_watermark(youtube, args.channelid, args.file, json.loads(args.metadata)) print "The watermark was successfully set."
Remove a watermark image from a channel
The following code sample calls the API's watermarks.unset
method to remove the watermark image for a channel. The request must be authorized by the channel that owns the video.
#!/usr/bin/python # Usage example: # python unset_watermark.py --channelId='<channel_id>' --unset import json import os import sys import httplib2 from apiclient.discovery import build from apiclient.errors import HttpError from oauth2client.file import Storage from oauth2client.client import flow_from_clientsecrets from oauth2client.tools import argparser, run_flow # CLIENT_SECRETS_FILE, name of a file containing the OAuth 2.0 information for # this application, including client_id and client_secret. You can acquire an # ID/secret pair from the API Access tab on the Google Developers Console # https://console.developers.google.com/project/_/apiui/credential # For more information about using OAuth2 to access Google APIs, please visit: # https://developers.google.com/accounts/docs/OAuth2 # For more information about the client_secrets.json file format, please visit: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets # Please ensure that you have enabled the YouTube Data API for your project. CLIENT_SECRETS_FILE = "client_secrets.json" # An OAuth 2 access scope that allows for full read/write access. YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" # Helpful 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 Developers Console https://console.developers.google.com 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)) # Authorize the request and store authorization credentials. def get_authenticated_service(args): flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE, message=MISSING_CLIENT_SECRETS_MESSAGE) 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())) # Call the API's watermarks.unset method to remove the watermark image. def unset_watermark(youtube, channel_id): try: youtube.watermarks().unset(channelId=channel_id).execute() except HttpError as e: print "Error while unsetting watermark: %s" % e.content raise e if __name__ == "__main__": argparser.add_argument("--channelid", dest="channelid", help="Required; id of channel whose watermark you're updating.") args = argparser.parse_args() if not args.channelid: argparser.print_help() exit() youtube = get_authenticated_service(args) unset_watermark(youtube, args.channelid) print "The watermark was successfully unset."