Skip to content

Commit 2fa8d26

Browse files
Support more options, update auth flow
Add command line options for setting content owner (for onBehalfOfContentOwner parameter) and for whether the script should list system-managed reports when listing reports. Instead of making --name a required command line argument, prompt the user to enter a name if one isn't set. This prompt occurs after the user selects a report type. Allow user to set report type on command line and thereby bypass the report type selection. The oauth2client library is deprecated. This update changes the sample to use the google-auth and google-auth-oauthlib libraries instead.
1 parent e084e3e commit 2fa8d26

File tree

1 file changed

+87
-73
lines changed

1 file changed

+87
-73
lines changed

Diff for: python/create_reporting_job.py

+87-73
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
#!/usr/bin/python
22

3+
# Create a reporting job for the authenticated user's channel or
4+
# for a content owner that the user's account is linked to.
35
# Usage example:
46
# python create_reporting_job.py --name='<name>'
7+
# python create_reporting_job.py --content-owner='<CONTENT OWNER ID>'
8+
# python create_reporting_job.py --content-owner='<CONTENT_OWNER_ID>' --report-type='<REPORT_TYPE_ID>' --name='<REPORT_NAME>'
59

6-
import httplib2
10+
import argparse
711
import os
8-
import sys
912

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
13+
import google.oauth2.credentials
14+
import google_auth_oauthlib.flow
15+
from googleapiclient.discovery import build
16+
from googleapiclient.errors import HttpError
17+
from google_auth_oauthlib.flow import InstalledAppFlow
1518

1619

1720
# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
@@ -25,98 +28,109 @@
2528
# https://developers.google.com/youtube/v3/guides/authentication
2629
# For more information about the client_secrets.json file format, see:
2730
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
28-
CLIENT_SECRETS_FILE = "client_secrets.json"
31+
CLIENT_SECRETS_FILE = 'client_secret.json'
2932

3033
# This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for
3134
# authenticated user's account. Any request that retrieves earnings or ad performance metrics must
3235
# use this scope.
33-
YOUTUBE_ANALYTICS_MONETARY_READ_SCOPE = (
34-
"https://www.googleapis.com/auth/yt-analytics-monetary.readonly")
35-
YOUTUBE_REPORTING_API_SERVICE_NAME = "youtubereporting"
36-
YOUTUBE_REPORTING_API_VERSION = "v1"
37-
38-
# This variable defines a message to display if the CLIENT_SECRETS_FILE is
39-
# missing.
40-
MISSING_CLIENT_SECRETS_MESSAGE = """
41-
WARNING: Please configure OAuth 2.0
42-
43-
To make this sample run you will need to populate the client_secrets.json file
44-
found at:
45-
%s
46-
with information from the APIs Console
47-
https://console.developers.google.com
48-
49-
For more information about the client_secrets.json file format, please visit:
50-
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
51-
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
52-
CLIENT_SECRETS_FILE))
36+
SCOPES = ['https://www.googleapis.com/auth/yt-analytics-monetary.readonly']
37+
API_SERVICE_NAME = 'youtubereporting'
38+
API_VERSION = 'v1'
5339

5440
# Authorize the request and store authorization credentials.
55-
def get_authenticated_service(args):
56-
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_ANALYTICS_MONETARY_READ_SCOPE,
57-
message=MISSING_CLIENT_SECRETS_MESSAGE)
58-
59-
storage = Storage("%s-oauth2.json" % sys.argv[0])
60-
credentials = storage.get()
61-
62-
if credentials is None or credentials.invalid:
63-
credentials = run_flow(flow, storage, args)
64-
65-
return build(YOUTUBE_REPORTING_API_SERVICE_NAME, YOUTUBE_REPORTING_API_VERSION,
66-
http=credentials.authorize(httplib2.Http()))
67-
41+
def get_authenticated_service():
42+
flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
43+
credentials = flow.run_console()
44+
return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
45+
46+
# Remove keyword arguments that are not set.
47+
def remove_empty_kwargs(**kwargs):
48+
good_kwargs = {}
49+
if kwargs is not None:
50+
for key, value in kwargs.iteritems():
51+
if value:
52+
good_kwargs[key] = value
53+
return good_kwargs
6854

6955
# Call the YouTube Reporting API's reportTypes.list method to retrieve report types.
70-
def list_report_types(youtube_reporting):
71-
results = youtube_reporting.reportTypes().list().execute()
72-
reportTypes = results["reportTypes"]
73-
74-
if "reportTypes" in results and results["reportTypes"]:
75-
reportTypes = results["reportTypes"]
56+
def list_report_types(youtube_reporting, **kwargs):
57+
# Provide keyword arguments that have values as request parameters.
58+
kwargs = remove_empty_kwargs(**kwargs)
59+
results = youtube_reporting.reportTypes().list(**kwargs).execute()
60+
reportTypes = results['reportTypes']
61+
62+
if 'reportTypes' in results and results['reportTypes']:
63+
reportTypes = results['reportTypes']
7664
for reportType in reportTypes:
77-
print "Report type id: %s\n name: %s\n" % (reportType["id"], reportType["name"])
65+
print 'Report type id: %s\n name: %s\n' % (reportType['id'], reportType['name'])
7866
else:
79-
print "No report types found"
67+
print 'No report types found'
8068
return False
8169

8270
return True
8371

8472

8573
# Call the YouTube Reporting API's jobs.create method to create a job.
86-
def create_reporting_job(youtube_reporting, report_type_id, name):
74+
def create_reporting_job(youtube_reporting, report_type_id, **kwargs):
75+
# Provide keyword arguments that have values as request parameters.
76+
kwargs = remove_empty_kwargs(**kwargs)
77+
8778
reporting_job = youtube_reporting.jobs().create(
8879
body=dict(
89-
reportTypeId=report_type_id,
90-
name=name
91-
)
80+
reportTypeId=args.report_type,
81+
name=args.name
82+
),
83+
**kwargs
9284
).execute()
9385

94-
print ("Reporting job '%s' created for reporting type '%s' at '%s'"
95-
% (reporting_job["name"], reporting_job["reportTypeId"],
96-
reporting_job["createTime"]))
86+
print ('Reporting job "%s" created for reporting type "%s" at "%s"'
87+
% (reporting_job['name'], reporting_job['reportTypeId'],
88+
reporting_job['createTime']))
9789

9890

9991
# Prompt the user to enter a report type id for the job. Then return the id.
10092
def get_report_type_id_from_user():
101-
report_type_id = raw_input("Please enter the reportTypeId for the job: ")
102-
print ("You chose '%s' as the report type Id for the job." % report_type_id)
93+
report_type_id = raw_input('Please enter the reportTypeId for the job: ')
94+
print ('You chose "%s" as the report type Id for the job.' % report_type_id)
10395
return report_type_id
10496

97+
# Prompt the user to set a job name
98+
def prompt_user_to_set_job_name():
99+
job_name = raw_input('Please set a name for the job: ')
100+
print ('Great! "%s" is a memorable name for this job.' % job_name)
101+
return job_name
102+
103+
104+
if __name__ == '__main__':
105+
parser = argparse.ArgumentParser()
106+
# The 'name' option specifies the name that will be used for the reporting job.
107+
parser.add_argument('--content-owner', default='',
108+
help='ID of content owner for which you are retrieving jobs and reports.')
109+
parser.add_argument('--include-system-managed', default=False,
110+
help='Whether the API response should include system-managed reports')
111+
parser.add_argument('--name', default='',
112+
help='Name for the reporting job. The script prompts you to set a name ' +
113+
'for the job if you do not provide one using this argument.')
114+
parser.add_argument('--report-type', default=None,
115+
help='The type of report for which you are creating a job.')
116+
args = parser.parse_args()
117+
118+
youtube_reporting = get_authenticated_service()
105119

106-
if __name__ == "__main__":
107-
# The "name" option specifies the name that will be used for the reporting job.
108-
argparser.add_argument("--name",
109-
help="Required; name for the reporting job.")
110-
args = argparser.parse_args()
111-
112-
if not args.name:
113-
exit("Please specify name using the --name= parameter.")
114-
115-
youtube_reporting = get_authenticated_service(args)
116120
try:
117-
if list_report_types(youtube_reporting):
118-
create_reporting_job(youtube_reporting, get_report_type_id_from_user(), args.name)
121+
# Prompt user to select report type if they didn't set one on command line.
122+
if not args.report_type:
123+
if list_report_types(youtube_reporting,
124+
onBehalfOfContentOwner=args.content_owner,
125+
includeSystemManaged=args.include_system_managed):
126+
args.report_type = get_report_type_id_from_user()
127+
# Prompt user to set job name if not set on command line.
128+
if not args.name:
129+
args.name = prompt_user_to_set_job_name()
130+
# Create the job.
131+
if args.report_type:
132+
create_reporting_job(youtube_reporting,
133+
args,
134+
onBehalfOfContentOwner=args.content_owner)
119135
except HttpError, e:
120-
print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
121-
else:
122-
print "Created reporting job."
136+
print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content)

0 commit comments

Comments
 (0)