Skip to content

Commit d45d4fe

Browse files
Update auth libs, default privacy status
The oauth2client library is deprecated. This update changes the sample to use the google-auth and google-auth-oauthlib libraries instead. This update also updates the default privacy status for videos uploaded via this script to "private". The privacy status can be changed using the --privacyStatus command line argument.
1 parent b374c1e commit d45d4fe

File tree

1 file changed

+46
-73
lines changed

1 file changed

+46
-73
lines changed

python/upload_video.py

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#!/usr/bin/python
22

3+
import argparse
34
import httplib
45
import httplib2
56
import os
67
import random
7-
import sys
88
import time
99

10-
from apiclient.discovery import build
11-
from apiclient.errors import HttpError
12-
from apiclient.http import MediaFileUpload
13-
from oauth2client.client import flow_from_clientsecrets
14-
from oauth2client.file import Storage
15-
from oauth2client.tools import argparser, run_flow
10+
import google.oauth2.credentials
11+
import google_auth_oauthlib.flow
12+
from googleapiclient.discovery import build
13+
from googleapiclient.errors import HttpError
14+
from googleapiclient.http import MediaFileUpload
15+
from google_auth_oauthlib.flow import InstalledAppFlow
1616

1717

1818
# Explicitly tell the underlying HTTP transport library not to retry, since
@@ -42,53 +42,27 @@
4242
# https://developers.google.com/youtube/v3/guides/authentication
4343
# For more information about the client_secrets.json file format, see:
4444
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
45-
CLIENT_SECRETS_FILE = "client_secrets.json"
45+
CLIENT_SECRETS_FILE = 'client_secret.json'
4646

4747
# This OAuth 2.0 access scope allows an application to upload files to the
4848
# authenticated user's YouTube channel, but doesn't allow other types of access.
49-
YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload"
50-
YOUTUBE_API_SERVICE_NAME = "youtube"
51-
YOUTUBE_API_VERSION = "v3"
49+
SCOPES = ['https://www.googleapis.com/auth/youtube.upload']
50+
API_SERVICE_NAME = 'youtube'
51+
API_VERSION = 'v3'
5252

53-
# This variable defines a message to display if the CLIENT_SECRETS_FILE is
54-
# missing.
55-
MISSING_CLIENT_SECRETS_MESSAGE = """
56-
WARNING: Please configure OAuth 2.0
53+
VALID_PRIVACY_STATUSES = ('public', 'private', 'unlisted')
5754

58-
To make this sample run you will need to populate the client_secrets.json file
59-
found at:
6055

61-
%s
62-
63-
with information from the {{ Cloud Console }}
64-
{{ https://cloud.google.com/console }}
65-
66-
For more information about the client_secrets.json file format, please visit:
67-
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
68-
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
69-
CLIENT_SECRETS_FILE))
70-
71-
VALID_PRIVACY_STATUSES = ("public", "private", "unlisted")
72-
73-
74-
def get_authenticated_service(args):
75-
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,
76-
scope=YOUTUBE_UPLOAD_SCOPE,
77-
message=MISSING_CLIENT_SECRETS_MESSAGE)
78-
79-
storage = Storage("%s-oauth2.json" % sys.argv[0])
80-
credentials = storage.get()
81-
82-
if credentials is None or credentials.invalid:
83-
credentials = run_flow(flow, storage, args)
84-
85-
return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
86-
http=credentials.authorize(httplib2.Http()))
56+
# Authorize the request and store authorization credentials.
57+
def get_authenticated_service():
58+
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
59+
credentials = flow.run_console()
60+
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
8761

8862
def initialize_upload(youtube, options):
8963
tags = None
9064
if options.keywords:
91-
tags = options.keywords.split(",")
65+
tags = options.keywords.split(',')
9266

9367
body=dict(
9468
snippet=dict(
@@ -104,14 +78,14 @@ def initialize_upload(youtube, options):
10478

10579
# Call the API's videos.insert method to create and upload the video.
10680
insert_request = youtube.videos().insert(
107-
part=",".join(body.keys()),
81+
part=','.join(body.keys()),
10882
body=body,
10983
# The chunksize parameter specifies the size of each chunk of data, in
11084
# bytes, that will be uploaded at a time. Set a higher value for
11185
# reliable connections as fewer chunks lead to faster uploads. Set a lower
11286
# value for better recovery on less reliable connections.
11387
#
114-
# Setting "chunksize" equal to -1 in the code below means that the entire
88+
# Setting 'chunksize' equal to -1 in the code below means that the entire
11589
# file will be uploaded in a single HTTP request. (If the upload fails,
11690
# it will still be retried where it left off.) This is usually a best
11791
# practice, but if you're using Python older than 2.6 or if you're
@@ -124,58 +98,57 @@ def initialize_upload(youtube, options):
12498

12599
# This method implements an exponential backoff strategy to resume a
126100
# failed upload.
127-
def resumable_upload(insert_request):
101+
def resumable_upload(request):
128102
response = None
129103
error = None
130104
retry = 0
131105
while response is None:
132106
try:
133-
print "Uploading file..."
134-
status, response = insert_request.next_chunk()
107+
print 'Uploading file...'
108+
status, response = request.next_chunk()
135109
if response is not None:
136110
if 'id' in response:
137-
print "Video id '%s' was successfully uploaded." % response['id']
111+
print 'Video id "%s" was successfully uploaded.' % response['id']
138112
else:
139-
exit("The upload failed with an unexpected response: %s" % response)
113+
exit('The upload failed with an unexpected response: %s' % response)
140114
except HttpError, e:
141115
if e.resp.status in RETRIABLE_STATUS_CODES:
142-
error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status,
116+
error = 'A retriable HTTP error %d occurred:\n%s' % (e.resp.status,
143117
e.content)
144118
else:
145119
raise
146120
except RETRIABLE_EXCEPTIONS, e:
147-
error = "A retriable error occurred: %s" % e
121+
error = 'A retriable error occurred: %s' % e
148122

149123
if error is not None:
150124
print error
151125
retry += 1
152126
if retry > MAX_RETRIES:
153-
exit("No longer attempting to retry.")
127+
exit('No longer attempting to retry.')
154128

155129
max_sleep = 2 ** retry
156130
sleep_seconds = random.random() * max_sleep
157-
print "Sleeping %f seconds and then retrying..." % sleep_seconds
131+
print 'Sleeping %f seconds and then retrying...' % sleep_seconds
158132
time.sleep(sleep_seconds)
159133

160134
if __name__ == '__main__':
161-
argparser.add_argument("--file", required=True, help="Video file to upload")
162-
argparser.add_argument("--title", help="Video title", default="Test Title")
163-
argparser.add_argument("--description", help="Video description",
164-
default="Test Description")
165-
argparser.add_argument("--category", default="22",
166-
help="Numeric video category. " +
167-
"See https://developers.google.com/youtube/v3/docs/videoCategories/list")
168-
argparser.add_argument("--keywords", help="Video keywords, comma separated",
169-
default="")
170-
argparser.add_argument("--privacyStatus", choices=VALID_PRIVACY_STATUSES,
171-
default=VALID_PRIVACY_STATUSES[0], help="Video privacy status.")
172-
args = argparser.parse_args()
173-
174-
if not os.path.exists(args.file):
175-
exit("Please specify a valid file using the --file= parameter.")
176-
177-
youtube = get_authenticated_service(args)
135+
parser = argparse.ArgumentParser()
136+
parser.add_argument('--file', required=True, help='Video file to upload')
137+
parser.add_argument('--title', help='Video title', default='Test Title')
138+
parser.add_argument('--description', help='Video description',
139+
default='Test Description')
140+
parser.add_argument('--category', default='22',
141+
help='Numeric video category. ' +
142+
'See https://developers.google.com/youtube/v3/docs/videoCategories/list')
143+
parser.add_argument('--keywords', help='Video keywords, comma separated',
144+
default='')
145+
parser.add_argument('--privacyStatus', choices=VALID_PRIVACY_STATUSES,
146+
default='private', help='Video privacy status.')
147+
args = parser.parse_args()
148+
149+
youtube = get_authenticated_service()
150+
178151
try:
179152
initialize_upload(youtube, args)
180153
except HttpError, e:
181-
print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
154+
print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content)

0 commit comments

Comments
 (0)