|
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