Python Code Samples

The following code samples, which use the Google APIs Client Library for Python , are available for the YouTube Content ID API .

Retrieve a content owner's managed channels

The following code sample calls the YouTube Data API's channels.list method to retrieve a list of channels managed by the content owner making the API request.

 #!/usr/bin/python 
 import 
  
 httplib2 
 import 
  
 os 
 import 
  
 sys 
 from 
  
 apiclient.discovery 
  
 import 
 build 
 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 API Console at 
 # https://console.cloud.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 API Console 
 https://console.cloud.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 
 )) 
 YOUTUBE_SCOPES 
 = 
 ( 
 # This OAuth 2.0 access scope allows for read-only access to the authenticated 
 # user's account, but not other types of account access. 
 "https://www.googleapis.com/auth/youtube.readonly" 
 , 
 # This OAuth 2.0 scope grants access to YouTube Content ID API functionality. 
 "https://www.googleapis.com/auth/youtubepartner" 
 ) 
 YOUTUBE_API_SERVICE_NAME 
 = 
 "youtube" 
 YOUTUBE_API_VERSION 
 = 
 "v3" 
 YOUTUBE_PARTNER_API_SERVICE_NAME 
 = 
 "youtubePartner" 
 YOUTUBE_PARTNER_API_VERSION 
 = 
 "v1" 
 # Authorize the request and store authorization credentials. 
 def 
  
 get_authenticated_services 
 ( 
 args 
 ): 
 flow 
 = 
 flow_from_clientsecrets 
 ( 
 CLIENT_SECRETS_FILE 
 , 
 scope 
 = 
 " " 
 . 
 join 
 ( 
 YOUTUBE_SCOPES 
 ), 
 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 
 ) 
 youtube 
 = 
 build 
 ( 
 YOUTUBE_API_SERVICE_NAME 
 , 
 YOUTUBE_API_VERSION 
 , 
 http 
 = 
 credentials 
 . 
 authorize 
 ( 
 httplib2 
 . 
 Http 
 ())) 
 youtube_partner 
 = 
 build 
 ( 
 YOUTUBE_PARTNER_API_SERVICE_NAME 
 , 
 YOUTUBE_PARTNER_API_VERSION 
 , 
 http 
 = 
 credentials 
 . 
 authorize 
 ( 
 httplib2 
 . 
 Http 
 ())) 
 return 
 ( 
 youtube 
 , 
 youtube_partner 
 ) 
 def 
  
 get_content_owner_id 
 ( 
 youtube_partner 
 ): 
 # Call the contentOwners.list method to retrieve the ID of the content 
 # owner associated with the currently authenticated user's account. If the 
 # authenticated user's has access to multiple YouTube content owner accounts, 
 # you need to iterate through the results to find the appropriate one. 
 content_owners_list_response 
 = 
 youtube_partner 
 . 
 contentOwners 
 () 
 . 
 list 
 ( 
 fetchMine 
 = 
 True 
 ) 
 . 
 execute 
 () 
 return 
 content_owners_list_response 
 [ 
 "items" 
 ][ 
 0 
 ][ 
 "id" 
 ] 
 def 
  
 list_managed_channels 
 ( 
 youtube 
 , 
 content_owner_id 
 ): 
 print 
 "Channels managed by content owner ' 
 %s 
 ':" 
 % 
 content_owner_id 
 # Retrieve a list of the channels that the content owner manages. 
 channels_list_request 
 = 
 youtube 
 . 
 channels 
 () 
 . 
 list 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 managedByMe 
 = 
 True 
 , 
 part 
 = 
 "snippet" 
 , 
 maxResults 
 = 
 50 
 ) 
 while 
 channels_list_request 
 : 
 channels_list_response 
 = 
 channels_list_request 
 . 
 execute 
 () 
 for 
 channel_item 
 in 
 channels_list_response 
 [ 
 "items" 
 ]: 
 channel_title 
 = 
 channel_item 
 [ 
 "snippet" 
 ][ 
 "title" 
 ] 
 channel_id 
 = 
 channel_item 
 [ 
 "id" 
 ] 
 print 
 " 
 %s 
 ( 
 %s 
 )" 
 % 
 ( 
 channel_title 
 , 
 channel_id 
 ) 
 channels_list_request 
 = 
 youtube 
 . 
 channels 
 () 
 . 
 list_next 
 ( 
 channels_list_request 
 , 
 channels_list_response 
 ) 
 if 
 __name__ 
 == 
 "__main__" 
 : 
 args 
 = 
 argparser 
 . 
 parse_args 
 () 
 ( 
 youtube 
 , 
 youtube_partner 
 ) 
 = 
 get_authenticated_services 
 ( 
 args 
 ) 
 content_owner_id 
 = 
 get_content_owner_id 
 ( 
 youtube_partner 
 ) 
 list_managed_channels 
 ( 
 youtube 
 , 
 content_owner_id 
 ) 

Create, manage, and use asset labels

The following code sample makes a series of API calls that demonstrate how to create and use asset labels to categorize and search for items in your asset library.

 #!/usr/bin/python 
 import 
  
 httplib 
 import 
  
 httplib2 
 import 
  
 logging 
 import 
  
 os 
 import 
  
 sys 
 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 
 # 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 message associated with the HTTP 401 error that's returned when a user 
 # authenticates with a non-CMS account. 
 INVALID_CREDENTIALS 
 = 
 "Invalid Credentials" 
 # The reason associated with the HTTP 409 error that's returned when an asset label 
 # with the same name already exists. 
 ASSETLABEL_EXISTS 
 = 
 "assetLabelExists" 
 # 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 API Console at 
 # https://console.cloud.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" 
 # The local file used to store the cached OAuth 2 credentials after going 
 # through a one-time browser-based login. 
 CACHED_CREDENTIALS_FILE 
 = 
 " 
 %s 
 -oauth2.json" 
 % 
 sys 
 . 
 argv 
 [ 
 0 
 ] 
 YOUTUBE_SCOPES 
 = 
 ( 
 # This OAuth 2.0 access scope allows for full read/write access to the 
 # authenticated user's account. 
 "https://www.googleapis.com/auth/youtube" 
 , 
 # This OAuth 2.0 scope grants access to YouTube Content ID API functionality. 
 "https://www.googleapis.com/auth/youtubepartner" 
 ,) 
 YOUTUBE_API_SERVICE_NAME 
 = 
 "youtube" 
 YOUTUBE_API_VERSION 
 = 
 "v3" 
 YOUTUBE_CONTENT_ID_API_SERVICE_NAME 
 = 
 "youtubePartner" 
 YOUTUBE_CONTENT_ID_API_VERSION 
 = 
 "v1" 
 # 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 API Console 
 https://console.cloud.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 
 = 
 " " 
 . 
 join 
 ( 
 YOUTUBE_SCOPES 
 ), 
 message 
 = 
 MISSING_CLIENT_SECRETS_MESSAGE 
 ) 
 storage 
 = 
 Storage 
 ( 
 CACHED_CREDENTIALS_FILE 
 ) 
 credentials 
 = 
 storage 
 . 
 get 
 () 
 if 
 credentials 
 is 
 None 
 or 
 credentials 
 . 
 invalid 
 : 
 credentials 
 = 
 run_flow 
 ( 
 flow 
 , 
 storage 
 , 
 args 
 ) 
 youtube_partner 
 = 
 build 
 ( 
 YOUTUBE_CONTENT_ID_API_SERVICE_NAME 
 , 
 YOUTUBE_CONTENT_ID_API_VERSION 
 , 
 http 
 = 
 credentials 
 . 
 authorize 
 ( 
 httplib2 
 . 
 Http 
 ()), 
 static_discovery 
 = 
 False 
 ) 
 return 
 youtube_partner 
 # Call the contentOwners.list method to retrieve the ID of the content 
 # owner associated with the currently authenticated user's account. If the 
 # authenticated user's has access to multiple YouTube CMS accounts, you will 
 # need to iterate through the results to find the appropriate one. 
 def 
  
 get_content_owner_id 
 ( 
 youtube_partner 
 ): 
 try 
 : 
 content_owners_list_response 
 = 
 youtube_partner 
 . 
 contentOwners 
 () 
 . 
 list 
 ( 
 fetchMine 
 = 
 True 
 ) 
 . 
 execute 
 () 
 except 
 HttpError 
 , 
 e 
 : 
 if 
 INVALID_CREDENTIALS 
 in 
 e 
 . 
 content 
 : 
 logging 
 . 
 error 
 ( 
 "You are not authenticated as a Google Account that has " 
 "YouTube CMS access. Please delete ' 
 %s 
 ' and re-authenticate with a " 
 "YouTube CMS account." 
 % 
 CACHED_CREDENTIALS_FILE 
 ) 
 exit 
 ( 
 1 
 ) 
 else 
 : 
 raise 
 return 
 content_owners_list_response 
 [ 
 "items" 
 ][ 
 0 
 ][ 
 "id" 
 ] 
 def 
  
 create_asset_label 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 labelName 
 ): 
 # Create a new asset label. 
 body 
 = 
 dict 
 ( 
 labelName 
 = 
 labelName 
 ) 
 try 
 : 
 asset_labels_insert_response 
 = 
 youtube_partner 
 . 
 assetLabels 
 () 
 . 
 insert 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 logging 
 . 
 info 
 ( 
 "Created new asset label ' 
 %s 
 '." 
 % 
 asset_labels_insert_response 
 [ 
 "labelName" 
 ]) 
 return 
 asset_labels_insert_response 
 [ 
 "labelName" 
 ] 
 except 
 HttpError 
 , 
 e 
 : 
 if 
 ASSETLABEL_EXISTS 
 in 
 e 
 . 
 content 
 : 
 logging 
 . 
 error 
 ( 
 "Asset label ' 
 %s 
 ' already exists." 
 % 
 labelName 
 ) 
 return 
 labelName 
 else 
 : 
 raise 
 def 
  
 list_asset_labels 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 ): 
 # Search for existing assets using labels. 
 asset_labels_list_response 
 = 
 youtube_partner 
 . 
 assetLabels 
 () 
 . 
 list 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 ) 
 . 
 execute 
 () 
 for 
 asset_label 
 in 
 asset_labels_list_response 
 . 
 get 
 ( 
 "items" 
 , 
 []): 
 logging 
 . 
 info 
 ( 
 "Found asset label ' 
 %s 
 '." 
 % 
 asset_label 
 [ 
 "labelName" 
 ]) 
 def 
  
 create_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 title 
 ): 
 # Create a new web asset, which corresponds to a video that was originally 
 # distributed online. 
 body 
 = 
 dict 
 ( 
 type 
 = 
 "web" 
 , 
 metadata 
 = 
 dict 
 ( 
 title 
 = 
 title 
 ) 
 ) 
 assets_insert_response 
 = 
 youtube_partner 
 . 
 assets 
 () 
 . 
 insert 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 return 
 assets_insert_response 
 def 
  
 search_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 include_any_label 
 , 
 labels 
 ): 
 # Search for existing assets using labels. 
 asset_search_response 
 = 
 youtube_partner 
 . 
 assetSearch 
 () 
 . 
 list 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 includeAnyProvidedlabel 
 = 
 include_any_label 
 , 
 labels 
 = 
 labels 
 ) 
 . 
 execute 
 () 
 for 
 asset 
 in 
 asset_search_response 
 . 
 get 
 ( 
 "items" 
 , 
 []): 
 logging 
 . 
 info 
 ( 
 "Found asset ID ' 
 %s 
 '." 
 % 
 asset 
 [ 
 "id" 
 ]) 
 def 
  
 update_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset 
 , 
 labels 
 ): 
 # Update an existing asset. 
 asset 
 [ 
 "label" 
 ] 
 = 
 labels 
 assets_update_response 
 = 
 youtube_partner 
 . 
 assets 
 () 
 . 
 update 
 ( 
 assetId 
 = 
 asset 
 [ 
 "id" 
 ], 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 body 
 = 
 asset 
 ) 
 . 
 execute 
 () 
 return 
 assets_update_response 
 if 
 __name__ 
 == 
 '__main__' 
 : 
 logging 
 . 
 basicConfig 
 ( 
 level 
 = 
 logging 
 . 
 DEBUG 
 , 
 format 
 = 
 " 
 %(asctime)s 
 [ 
 %(name)s 
 ] 
 %(levelname)s 
 : 
 %(message)s 
 " 
 , 
 datefmt 
 = 
 "%Y-%m- 
 %d 
 %H:%M:%S" 
 ) 
 args 
 = 
 argparser 
 . 
 parse_args 
 () 
 youtube_partner 
 = 
 get_authenticated_service 
 ( 
 args 
 ) 
 content_owner_id 
 = 
 get_content_owner_id 
 ( 
 youtube_partner 
 ) 
 logging 
 . 
 info 
 ( 
 "Authenticated as CMS user ID ' 
 %s 
 '." 
 % 
 content_owner_id 
 ) 
 asset_label_name 
 = 
 create_asset_label 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 "label1" 
 ); 
 list_asset_labels 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 ) 
 asset1 
 = 
 create_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 "asset1" 
 ) 
 logging 
 . 
 info 
 ( 
 "Created new asset ID ' 
 %s 
 '." 
 % 
 asset1 
 [ 
 "id" 
 ]) 
 asset1 
 = 
 update_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset1 
 , 
 [ 
 asset_label_name 
 , 
 "label3" 
 ]) 
 logging 
 . 
 info 
 ( 
 "Added asset labels ' 
 %s 
  
 %s 
 ' to ' 
 %s 
 '." 
 % 
 ( 
 asset1 
 [ 
 "label" 
 ][ 
 0 
 ], 
 asset1 
 [ 
 "label" 
 ][ 
 1 
 ], 
 asset1 
 [ 
 "id" 
 ])) 
 asset2 
 = 
 create_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 "asset2" 
 ) 
 logging 
 . 
 info 
 ( 
 "Created new asset ID ' 
 %s 
 '." 
 % 
 asset2 
 [ 
 "id" 
 ]) 
 asset2 
 = 
 update_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset2 
 , 
 [ 
 "label3" 
 ]) 
 logging 
 . 
 info 
 ( 
 "Added asset label ' 
 %s 
 ' to ' 
 %s 
 '." 
 % 
 ( 
 asset2 
 [ 
 "label" 
 ][ 
 0 
 ], 
 asset2 
 [ 
 "id" 
 ])) 
 list_asset_labels 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 ) 
 # AssetSearch may not be able to return the expected results right away, as there is a delay 
 # in indexing the assets with labels for the asset search after they are added. 
 # Second run of the code sample after this delay will return the expected assets 
 # of the previous run. 
 search_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 "label1, label3" 
 , 
 None 
 ) 
 search_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 "label1, label3" 
 , 
 True 
 ) 
 logging 
 . 
 info 
 ( 
 "All done!" 
 ) 

Create an asset; upload and claim a video

The following code sample makes a series of API calls to create an asset and set ownership for that asset, upload a video, claim the video as a match of the asset, and set advertising options for the video.

 #!/usr/bin/python 
 import 
  
 httplib 
 import 
  
 httplib2 
 import 
  
 logging 
 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.file 
  
 import 
 Storage 
 from 
  
 oauth2client.client 
  
 import 
 flow_from_clientsecrets 
 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 message associated with the HTTP 401 error that's returned when a user 
 # authenticates with a non-CMS account. 
 INVALID_CREDENTIALS 
 = 
 "Invalid Credentials" 
 # 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 API Console at 
 # https://console.cloud.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" 
 # The local file used to store the cached OAuth 2 credentials after going 
 # through a one-time browser-based login. 
 CACHED_CREDENTIALS_FILE 
 = 
 " 
 %s 
 -oauth2.json" 
 % 
 sys 
 . 
 argv 
 [ 
 0 
 ] 
 YOUTUBE_SCOPES 
 = 
 ( 
 # This OAuth 2.0 access scope allows for full read/write access to the 
 # authenticated user's account. 
 "https://www.googleapis.com/auth/youtube" 
 , 
 # This OAuth 2.0 scope grants access to YouTube Content ID API functionality. 
 "https://www.googleapis.com/auth/youtubepartner" 
 ,) 
 YOUTUBE_API_SERVICE_NAME 
 = 
 "youtube" 
 YOUTUBE_API_VERSION 
 = 
 "v3" 
 YOUTUBE_CONTENT_ID_API_SERVICE_NAME 
 = 
 "youtubePartner" 
 YOUTUBE_CONTENT_ID_API_VERSION 
 = 
 "v1" 
 # 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 API Console 
 https://console.cloud.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 
  
 parse_args 
 (): 
 argparser 
 . 
 add_argument 
 ( 
 "--file" 
 , 
 dest 
 = 
 "file" 
 , 
 help 
 = 
 "Video file to upload" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--title" 
 , 
 dest 
 = 
 "title" 
 , 
 help 
 = 
 "Video title" 
 , 
 default 
 = 
 "Test Title" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--description" 
 , 
 dest 
 = 
 "description" 
 , 
 help 
 = 
 "Video description" 
 , 
 default 
 = 
 "Test Description" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--category" 
 , 
 dest 
 = 
 "category" 
 , 
 help 
 = 
 "Numeric video category. " 
 + 
 "See https://developers.google.com/youtube/v3/docs/videoCategories/list" 
 , 
 default 
 = 
 "22" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--keywords" 
 , 
 dest 
 = 
 "keywords" 
 , 
 help 
 = 
 "Video keywords, comma separated" 
 , 
 default 
 = 
 "" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--privacyStatus" 
 , 
 dest 
 = 
 "privacyStatus" 
 , 
 help 
 = 
 "Video privacy status: public, private or unlisted" 
 , 
 default 
 = 
 "public" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--policyId" 
 , 
 dest 
 = 
 "policyId" 
 , 
 help 
 = 
 "Optional id of a saved claim policy" 
 ) 
 argparser 
 . 
 add_argument 
 ( 
 "--channelId" 
 , 
 dest 
 = 
 "channelId" 
 , 
 help 
 = 
 "Id of the channel to upload to. Must be managed by your " 
 + 
 "content owner account" 
 ) 
 args 
 = 
 argparser 
 . 
 parse_args 
 () 
 return 
 args 
 # Authorize the request and store authorization credentials. 
 def 
  
 get_authenticated_services 
 ( 
 args 
 ): 
 flow 
 = 
 flow_from_clientsecrets 
 ( 
 CLIENT_SECRETS_FILE 
 , 
 scope 
 = 
 " " 
 . 
 join 
 ( 
 YOUTUBE_SCOPES 
 ), 
 message 
 = 
 MISSING_CLIENT_SECRETS_MESSAGE 
 ) 
 storage 
 = 
 Storage 
 ( 
 CACHED_CREDENTIALS_FILE 
 ) 
 credentials 
 = 
 storage 
 . 
 get 
 () 
 if 
 credentials 
 is 
 None 
 or 
 credentials 
 . 
 invalid 
 : 
 credentials 
 = 
 run_flow 
 ( 
 flow 
 , 
 storage 
 , 
 args 
 ) 
 youtube 
 = 
 build 
 ( 
 YOUTUBE_API_SERVICE_NAME 
 , 
 YOUTUBE_API_VERSION 
 , 
 http 
 = 
 credentials 
 . 
 authorize 
 ( 
 httplib2 
 . 
 Http 
 ())) 
 youtube_partner 
 = 
 build 
 ( 
 YOUTUBE_CONTENT_ID_API_SERVICE_NAME 
 , 
 YOUTUBE_CONTENT_ID_API_VERSION 
 , 
 http 
 = 
 credentials 
 . 
 authorize 
 ( 
 httplib2 
 . 
 Http 
 ()), 
 static_discovery 
 = 
 False 
 ) 
 return 
 ( 
 youtube 
 , 
 youtube_partner 
 ) 
 # Call the contentOwners.list method to retrieve the ID of the content 
 # owner associated with the currently authenticated user's account. If the 
 # authenticated user's has access to multiple YouTube content owner accounts, you will 
 # need to iterate through the results to find the appropriate one. 
 def 
  
 get_content_owner_id 
 ( 
 youtube_partner 
 ): 
 try 
 : 
 content_owners_list_response 
 = 
 youtube_partner 
 . 
 contentOwners 
 () 
 . 
 list 
 ( 
 fetchMine 
 = 
 True 
 ) 
 . 
 execute 
 () 
 except 
 HttpError 
 , 
 e 
 : 
 if 
 INVALID_CREDENTIALS 
 in 
 e 
 . 
 content 
 : 
 logging 
 . 
 error 
 ( 
 "You are not authenticated using the Google Account for " 
 "a YouTube content owner. Please delete ' 
 %s 
 ' and re-authenticate as a " 
 "YouTube content owner." 
 % 
 CACHED_CREDENTIALS_FILE 
 ) 
 exit 
 ( 
 1 
 ) 
 else 
 : 
 raise 
 return 
 content_owners_list_response 
 [ 
 "items" 
 ][ 
 0 
 ][ 
 "id" 
 ] 
 def 
  
 upload 
 ( 
 youtube 
 , 
 content_owner_id 
 , 
 args 
 ): 
 if 
 args 
 . 
 keywords 
 : 
 tags 
 = 
 args 
 . 
 keywords 
 . 
 split 
 ( 
 "," 
 ) 
 else 
 : 
 tags 
 = 
 None 
 # Call the YouTube Data API's videos.insert method to create and upload 
 # the video. 
 insert_request 
 = 
 youtube 
 . 
 videos 
 () 
 . 
 insert 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 onBehalfOfContentOwnerChannel 
 = 
 args 
 . 
 channelId 
 , 
 part 
 = 
 "snippet,status" 
 , 
 body 
 = 
 dict 
 ( 
 snippet 
 = 
 dict 
 ( 
 title 
 = 
 args 
 . 
 title 
 , 
 description 
 = 
 args 
 . 
 description 
 , 
 tags 
 = 
 tags 
 , 
 categoryId 
 = 
 args 
 . 
 category 
 ), 
 status 
 = 
 dict 
 ( 
 privacyStatus 
 = 
 args 
 . 
 privacyStatus 
 ) 
 ), 
 # 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 
 ( 
 args 
 . 
 file 
 , 
 chunksize 
 =- 
 1 
 , 
 resumable 
 = 
 True 
 ) 
 ) 
 # This code uses an exponential backoff strategy to resume a failed upload. 
 response 
 = 
 None 
 error 
 = 
 None 
 retry 
 = 
 0 
 duration_seconds 
 = 
 0 
 while 
 response 
 is 
 None 
 : 
 try 
 : 
 logging 
 . 
 debug 
 ( 
 "Uploading file..." 
 ) 
 start_seconds 
 = 
 time 
 . 
 time 
 () 
 status 
 , 
 response 
 = 
 insert_request 
 . 
 next_chunk 
 () 
 delta_seconds 
 = 
 time 
 . 
 time 
 () 
 - 
 start_seconds 
 duration_seconds 
 += 
 delta_seconds 
 if 
 "id" 
 in 
 response 
 : 
 return 
 ( 
 response 
 [ 
 "id" 
 ], 
 duration_seconds 
 ) 
 else 
 : 
 logging 
 . 
 error 
 ( 
 "The upload failed with an unexpected response: 
 %s 
 " 
 % 
 response 
 ) 
 exit 
 ( 
 1 
 ) 
 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 
 : 
 logging 
 . 
 error 
 ( 
 error 
 ) 
 retry 
 += 
 1 
 if 
 retry 
> MAX_RETRIES 
 : 
 logging 
 . 
 error 
 ( 
 "No longer attempting to retry." 
 ) 
 exit 
 ( 
 1 
 ) 
 max_sleep 
 = 
 2 
 ** 
 retry 
 sleep_seconds 
 = 
 random 
 . 
 random 
 () 
 * 
 max_sleep 
 logging 
 . 
 debug 
 ( 
 "Sleeping 
 %f 
 seconds and then retrying..." 
 % 
 sleep_seconds 
 ) 
 time 
 . 
 sleep 
 ( 
 sleep_seconds 
 ) 
 def 
  
 create_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 title 
 , 
 description 
 ): 
 # Create a new web asset, which corresponds to a video that was originally 
 # distributed online. The asset will be linked to the corresponding YouTube 
 # video via a claim that is created later in the script. 
 body 
 = 
 dict 
 ( 
 type 
 = 
 "web" 
 , 
 metadata 
 = 
 dict 
 ( 
 title 
 = 
 title 
 , 
 description 
 = 
 description 
 ) 
 ) 
 assets_insert_response 
 = 
 youtube_partner 
 . 
 assets 
 () 
 . 
 insert 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 return 
 assets_insert_response 
 [ 
 "id" 
 ] 
 def 
  
 set_asset_ownership 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset_id 
 ): 
 # Update the asset's ownership data. This example indicates that the content 
 # owner owns 100% of the asset worldwide. 
 body 
 = 
 dict 
 ( 
 general 
 = 
 [ 
 dict 
 ( 
 owner 
 = 
 content_owner_id 
 , 
 ratio 
 = 
 100 
 , 
 type 
 = 
 "exclude" 
 , 
 territories 
 = 
 [] 
 )] 
 ) 
 youtube_partner 
 . 
 ownership 
 () 
 . 
 update 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 assetId 
 = 
 asset_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 def 
  
 claim_video 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset_id 
 , 
 video_id 
 , 
 policy_id 
 ): 
 # Create a claim resource. Identify the video being claimed, the asset 
 # that represents the claimed content, the type of content being claimed, 
 # and the policy that you want to apply to the claimed video. 
 # 
 # You can identify a policy by using the policy_id of an existing policy as 
 # obtained via youtubePartner.policies.list(). If you update that policy at 
 # a later time, the updated policy will also be applied to a claim. If you 
 # do not provide a policy_id, the code creates a new inline policy that 
 # indicates that the video should be monetized. 
 if 
 policy_id 
 : 
 policy 
 = 
 dict 
 ( 
 id 
 = 
 policy_id 
 ) 
 else 
 : 
 policy 
 = 
 dict 
 ( 
 rules 
 = 
 [ 
 dict 
 ( 
 action 
 = 
 "monetize" 
 )] 
 ) 
 body 
 = 
 dict 
 ( 
 assetId 
 = 
 asset_id 
 , 
 videoId 
 = 
 video_id 
 , 
 policy 
 = 
 policy 
 , 
 contentType 
 = 
 "audiovisual" 
 ) 
 claims_insert_response 
 = 
 youtube_partner 
 . 
 claims 
 () 
 . 
 insert 
 ( 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 return 
 claims_insert_response 
 [ 
 "id" 
 ] 
 def 
  
 set_advertising_options 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 video_id 
 ): 
 # Enable ads for the video. This example enables the TrueView ad format. 
 body 
 = 
 dict 
 ( 
 adFormats 
 = 
 [ 
 "trueview_instream" 
 ] 
 ) 
 youtube_partner 
 . 
 videoAdvertisingOptions 
 () 
 . 
 update 
 ( 
 videoId 
 = 
 video_id 
 , 
 onBehalfOfContentOwner 
 = 
 content_owner_id 
 , 
 body 
 = 
 body 
 ) 
 . 
 execute 
 () 
 if 
 __name__ 
 == 
 '__main__' 
 : 
 logging 
 . 
 basicConfig 
 ( 
 level 
 = 
 logging 
 . 
 DEBUG 
 , 
 format 
 = 
 " 
 %(asctime)s 
 [ 
 %(name)s 
 ] 
 %(levelname)s 
 : 
 %(message)s 
 " 
 , 
 datefmt 
 = 
 "%Y-%m- 
 %d 
 %H:%M:%S" 
 ) 
 args 
 = 
 parse_args 
 () 
 if 
 args 
 . 
 file 
 is 
 None 
 or 
 not 
 os 
 . 
 path 
 . 
 exists 
 ( 
 args 
 . 
 file 
 ): 
 logging 
 . 
 error 
 ( 
 "Please specify a valid file using the --file= parameter." 
 ) 
 exit 
 ( 
 1 
 ) 
 # The channel ID value has a format like "UC..." and must identify a channel 
 # managed by the YouTube content owner associated with the authenticated user. 
 # You can use the YouTube Data API's youtube.channels.list method to 
 # retrieve a list of managed channels and their IDs. (To do so, set the 
 # "part" parameter value to "snippet", the "managedByMe" parameter value to 
 # "true" and the "onBehalfOfContentOwner" parameter to the content owner ID. 
 # The "get_content_owner_id" method in this code sample shows how 
 # to retrieve the content owner ID. 
 if 
 args 
 . 
 channelId 
 is 
 None 
 : 
 logging 
 . 
 error 
 ( 
 "Please specify a channel ID via the --channelId= parameter." 
 ) 
 exit 
 ( 
 1 
 ) 
 ( 
 youtube 
 , 
 youtube_partner 
 ) 
 = 
 get_authenticated_services 
 ( 
 args 
 ) 
 content_owner_id 
 = 
 get_content_owner_id 
 ( 
 youtube_partner 
 ) 
 logging 
 . 
 info 
 ( 
 "Authenticated as content owner ID ' 
 %s 
 '." 
 % 
 content_owner_id 
 ) 
 ( 
 video_id 
 , 
 duration_seconds 
 ) 
 = 
 upload 
 ( 
 youtube 
 , 
 content_owner_id 
 , 
 args 
 ) 
 logging 
 . 
 info 
 ( 
 "Successfully uploaded video ID ' 
 %s 
 '." 
 % 
 video_id 
 ) 
 file_size_bytes 
 = 
 os 
 . 
 path 
 . 
 getsize 
 ( 
 args 
 . 
 file 
 ) 
 logging 
 . 
 debug 
 ( 
 "Uploaded 
 %d 
 bytes in 
 %0.2f 
 seconds ( 
 %0.2f 
 megabytes/second)." 
 % 
 ( 
 file_size_bytes 
 , 
 duration_seconds 
 , 
 ( 
 file_size_bytes 
 / 
 ( 
 1024 
 * 
 1024 
 )) 
 / 
 duration_seconds 
 )) 
 asset_id 
 = 
 create_asset 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 args 
 . 
 title 
 , 
 args 
 . 
 description 
 ) 
 logging 
 . 
 info 
 ( 
 "Created new asset ID ' 
 %s 
 '." 
 % 
 asset_id 
 ) 
 set_asset_ownership 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset_id 
 ) 
 logging 
 . 
 info 
 ( 
 "Successfully set asset ownership." 
 ) 
 claim_id 
 = 
 claim_video 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 asset_id 
 , 
 video_id 
 , 
 args 
 . 
 policyId 
 ) 
 logging 
 . 
 info 
 ( 
 "Created new claim ID ' 
 %s 
 '." 
 % 
 claim_id 
 ) 
 set_advertising_options 
 ( 
 youtube_partner 
 , 
 content_owner_id 
 , 
 video_id 
 ) 
 logging 
 . 
 info 
 ( 
 "Successfully set advertising options." 
 ) 
 logging 
 . 
 info 
 ( 
 "All done!" 
 ) 
Create a Mobile Website
View Site in Mobile | Classic
Share by: