Skip to content

Commit 3702238

Browse files
Update auth libraries, fix brandingSettings update
The oauth2client library is deprecated. This update changes the sample to use the google-auth and google-auth-oauthlib libraries instead. Update code sample to update brandingSettings (defaultLanguage) and localizations separately. Support localized channel title and localized channel description.
1 parent f058c43 commit 3702238

File tree

1 file changed

+87
-84
lines changed

1 file changed

+87
-84
lines changed

python/channel_localizations.py

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

33
# Usage example:
4-
# python channel_localizations.py --action='<action>' --channel_id='<channel_id>' --default_language='<default_language>' --language='<language>' --description='<description>'
4+
# python channel_localizations.py --action='<action>' --channel_id='<channel_id>' --default_language='<default_language>' --language='<language>' --title='<title>' --description='<description>'
55

6-
import httplib2
6+
import argparse
77
import os
8-
import sys
8+
import re
99

10-
from apiclient.discovery import build
11-
from apiclient.errors import HttpError
12-
from oauth2client.client import flow_from_clientsecrets
13-
from oauth2client.file import Storage
14-
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 google_auth_oauthlib.flow import InstalledAppFlow
1515

1616

1717
# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
@@ -25,137 +25,140 @@
2525
# https://developers.google.com/youtube/v3/guides/authentication
2626
# For more information about the client_secrets.json file format, see:
2727
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
28-
CLIENT_SECRETS_FILE = "client_secrets.json"
28+
CLIENT_SECRETS_FILE = 'client_secret.json'
2929

3030
# This OAuth 2.0 access scope allows for full read/write access to the
3131
# authenticated user's account.
32-
YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube"
33-
YOUTUBE_API_SERVICE_NAME = "youtube"
34-
YOUTUBE_API_VERSION = "v3"
35-
36-
# This variable defines a message to display if the CLIENT_SECRETS_FILE is
37-
# missing.
38-
MISSING_CLIENT_SECRETS_MESSAGE = """
39-
WARNING: Please configure OAuth 2.0
40-
41-
To make this sample run you will need to populate the client_secrets.json file
42-
found at:
43-
%s
44-
with information from the APIs Console
45-
https://console.developers.google.com
46-
47-
For more information about the client_secrets.json file format, please visit:
48-
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
49-
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
50-
CLIENT_SECRETS_FILE))
32+
SCOPES = ['https://www.googleapis.com/auth/youtube']
33+
API_SERVICE_NAME = 'youtube'
34+
API_VERSION = 'v3'
5135

5236
# Authorize the request and store authorization credentials.
53-
def get_authenticated_service(args):
54-
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_READ_WRITE_SCOPE,
55-
message=MISSING_CLIENT_SECRETS_MESSAGE)
56-
57-
storage = Storage("%s-oauth2.json" % sys.argv[0])
58-
credentials = storage.get()
59-
60-
if credentials is None or credentials.invalid:
61-
credentials = run_flow(flow, storage, args)
62-
63-
return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
64-
http=credentials.authorize(httplib2.Http()))
65-
37+
def get_authenticated_service():
38+
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
39+
credentials = flow.run_console()
40+
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
6641

6742
# Call the API's channels.update method to update an existing channel's default language,
6843
# and localized description in a specific language.
69-
def set_channel_localization(youtube, channel_id, default_language, language, description):
44+
def set_channel_localization(youtube, args):
7045
results = youtube.channels().list(
71-
part="brandingSettings,localizations",
72-
id=channel_id
46+
part='localizations',
47+
id=args.channel_id
7348
).execute()
7449

75-
channel = results["items"][0]
50+
channel = results['items'][0]
51+
7652
# Ensure that a value is set for the resource's snippet.defaultLanguage property.
7753
# To set the snippet.defaultLanguage property for a channel resource,
7854
# you actually need to update the brandingSettings.channel.defaultLanguage property.
79-
channel["brandingSettings"]["channel"]["defaultLanguage"] = default_language
80-
if "localizations" not in channel:
81-
channel["localizations"] = {}
82-
channel["localizations"][language] = {
83-
"description": description
55+
if 'localizations' not in channel:
56+
channel['localizations'] = {}
57+
if args.title and args.description and args.language:
58+
channel['localizations'][args.language] = {
59+
'title': args.title,
60+
'description': args.description
8461
}
8562

63+
# Set the default language if it is provided as an argument
64+
if args.default_language:
65+
results = youtube.channels().list(
66+
part='brandingSettings',
67+
id=args.channel_id
68+
).execute()
69+
branding_settings_channel = results['items'][0]
70+
# This property must be removed when changing the default language
71+
# or set to the original channel title to avoid a
72+
# channelTitleUpdateForbidden error.
73+
del branding_settings_channel['brandingSettings']['channel']['title']
74+
branding_settings_channel['brandingSettings']['channel']['defaultLanguage'] = (
75+
args.default_language)
76+
language_result = youtube.channels().update(
77+
part='brandingSettings',
78+
body=branding_settings_channel
79+
).execute()
80+
updated_default_language = (
81+
language_result['brandingSettings']['channel']['defaultLanguage'])
82+
print 'Updated language to %s' % updated_default_language
83+
8684
update_result = youtube.channels().update(
87-
part="brandingSettings,localizations",
85+
part='localizations',
8886
body=channel
8987
).execute()
9088

91-
localization = update_result["localizations"][language]
89+
localization = update_result['localizations'][args.language]
9290

93-
print ("Updated channel '%s' default language to '%s', localized description"
94-
" to '%s' in language '%s'" % (channel_id, localization["description"], language))
91+
print ('Updated channel \'%s\' localized title and description to '
92+
'\'%s\' and \'%s\' in language \'%s\'' %
93+
(args.channel_id, localization['title'], localization['description'], args.language))
9594

9695

9796
# Call the API's channels.list method to retrieve an existing channel localization.
9897
# If the localized text is not available in the requested language,
9998
# this method will return text in the default language.
10099
def get_channel_localization(youtube, channel_id, language):
101100
results = youtube.channels().list(
102-
part="snippet",
101+
part='snippet',
103102
id=channel_id,
104103
hl=language
105104
).execute()
106105

107106
# The localized object contains localized text if the hl parameter specified
108107
# a language for which localized text is available. Otherwise, the localized
109108
# object will contain metadata in the default language.
110-
localized = results["items"][0]["snippet"]["localized"]
109+
localized = results['items'][0]['snippet']['localized']
111110

112-
print "Channel description is '%s' in language '%s'" % (localized["description"], language)
111+
print 'Channel description is \'%s\' in language \'%s\'' % (localized['description'], language)
113112

114113

115114
# Call the API's channels.list method to list the existing channel localizations.
116115
def list_channel_localizations(youtube, channel_id):
117116
results = youtube.channels().list(
118-
part="snippet,localizations",
117+
part='snippet,localizations',
119118
id=channel_id
120119
).execute()
121120

122-
localizations = results["items"][0]["localizations"]
121+
localizations = results['items'][0]['localizations']
123122

124123
for language, localization in localizations.iteritems():
125-
print "Channel description is '%s' in language '%s'" % (localization["description"], language)
126-
127-
128-
if __name__ == "__main__":
129-
# The "action" option specifies the action to be processed.
130-
argparser.add_argument("--action", help="Action")
131-
# The "channel_id" option specifies the ID of the selected YouTube channel.
132-
argparser.add_argument("--channel_id",
133-
help="ID for channel for which the localization will be applied.")
134-
# The "default_language" option specifies the language of the channel's default metadata.
135-
argparser.add_argument("--default_language", help="Default language of the channel to update.",
136-
default="en")
137-
# The "language" option specifies the language of the localization that is being processed.
138-
argparser.add_argument("--language", help="Language of the localization.", default="de")
139-
# The "description" option specifies the localized description of the chanel to be set.
140-
argparser.add_argument("--description", help="Localized description of the channel to be set.",
141-
default="Localized Description")
142-
143-
args = argparser.parse_args()
124+
print 'Channel description is \'%s\' in language \'%s\'' % (localization['description'], language)
125+
126+
127+
if __name__ == '__main__':
128+
parser = argparse.ArgumentParser()
129+
# The 'action' option specifies the action to be processed.
130+
parser.add_argument('--action', help='Action')
131+
# The 'channel_id' option specifies the ID of the selected YouTube channel.
132+
parser.add_argument('--channel_id',
133+
help='ID for channel for which the localization will be applied.')
134+
# The 'default_language' option specifies the language of the channel's default metadata.
135+
parser.add_argument('--default_language', help='Default language of the channel to update.',
136+
default=None)
137+
# The 'language' option specifies the language of the localization that is being processed.
138+
parser.add_argument('--language', help='Language of the localization.', default='de')
139+
# The 'title' option specifies the localized title of the chanel to be set.
140+
parser.add_argument('--title', help='Localized title of the channel to be set.',
141+
default='Localized title')
142+
# The 'description' option specifies the localized description of the chanel to be set.
143+
parser.add_argument('--description', help='Localized description of the channel to be set.',
144+
default='Localized description')
145+
146+
args = parser.parse_args()
144147

145148
if not args.channel_id:
146-
exit("Please specify channel id using the --channel_id= parameter.")
149+
exit('Please specify channel id using the --channel_id= parameter.')
147150

148-
youtube = get_authenticated_service(args)
151+
youtube = get_authenticated_service()
149152
try:
150153
if args.action == 'set':
151-
set_channel_localization(youtube, args.channel_id, args.default_language, args.language, args.description)
154+
set_channel_localization(youtube, args)
152155
elif args.action == 'get':
153156
get_channel_localization(youtube, args.channel_id, args.language)
154157
elif args.action == 'list':
155158
list_channel_localizations(youtube, args.channel_id)
156159
else:
157-
exit("Please specify a valid action using the --action= parameter.")
160+
exit('Please specify a valid action using the --action= parameter.')
158161
except HttpError, e:
159-
print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
162+
print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content)
160163
else:
161-
print "Set and retrieved localized metadata for a channel."
164+
print 'Set or retrieved localized metadata for a channel.'

0 commit comments

Comments
 (0)