|
1 | 1 | #!/usr/bin/python
|
2 | 2 |
|
| 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. |
3 | 5 | # Usage example:
|
4 | 6 | # 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>' |
5 | 9 |
|
6 |
| -import httplib2 |
| 10 | +import argparse |
7 | 11 | import os
|
8 |
| -import sys |
9 | 12 |
|
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 |
15 | 18 |
|
16 | 19 |
|
17 | 20 | # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
|
|
25 | 28 | # https://developers.google.com/youtube/v3/guides/authentication
|
26 | 29 | # For more information about the client_secrets.json file format, see:
|
27 | 30 | # 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' |
29 | 32 |
|
30 | 33 | # This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for
|
31 | 34 | # authenticated user's account. Any request that retrieves earnings or ad performance metrics must
|
32 | 35 | # 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' |
53 | 39 |
|
54 | 40 | # 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 |
68 | 54 |
|
69 | 55 | # 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'] |
76 | 64 | 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']) |
78 | 66 | else:
|
79 |
| - print "No report types found" |
| 67 | + print 'No report types found' |
80 | 68 | return False
|
81 | 69 |
|
82 | 70 | return True
|
83 | 71 |
|
84 | 72 |
|
85 | 73 | # 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 | + |
87 | 78 | reporting_job = youtube_reporting.jobs().create(
|
88 | 79 | body=dict(
|
89 |
| - reportTypeId=report_type_id, |
90 |
| - name=name |
91 |
| - ) |
| 80 | + reportTypeId=args.report_type, |
| 81 | + name=args.name |
| 82 | + ), |
| 83 | + **kwargs |
92 | 84 | ).execute()
|
93 | 85 |
|
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'])) |
97 | 89 |
|
98 | 90 |
|
99 | 91 | # Prompt the user to enter a report type id for the job. Then return the id.
|
100 | 92 | 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) |
103 | 95 | return report_type_id
|
104 | 96 |
|
| 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() |
105 | 119 |
|
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) |
116 | 120 | 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) |
119 | 135 | 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