Skip to content

Commit 4566c52

Browse files
committed
"Added sample: python/batch_report_download.py"
1 parent 5aeae9d commit 4566c52

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

python/batch_report_download.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#!/usr/bin/python
2+
3+
import httplib2
4+
import os
5+
import sys
6+
import urllib
7+
8+
from apiclient.discovery import build, build_from_document
9+
from apiclient.errors import HttpError
10+
from apiclient.http import MediaIoBaseDownload
11+
from oauth2client.client import flow_from_clientsecrets
12+
from oauth2client.file import Storage
13+
from oauth2client.tools import argparser, run_flow
14+
15+
16+
# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
17+
# the OAuth 2.0 information for this application, including its client_id and
18+
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from
19+
# the Google Cloud Console at
20+
# https://cloud.google.com/console.
21+
# Please ensure that you have enabled the YouTube Analytics API for your project.
22+
# For more information about using OAuth2 to access Google APIs, see:
23+
# https://developers.google.com/youtube/v3/guides/authentication
24+
# For more information about the client_secrets.json file format, see:
25+
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
26+
CLIENT_SECRETS_FILE = "client_secrets.json"
27+
28+
# This OAuth 2.0 access scope allows for full read/write access to the
29+
# authenticated user's account.
30+
SCOPES = ("https://www.googleapis.com/auth/yt-analytics-monetary.readonly",
31+
"https://www.googleapis.com/auth/yt-analytics.readonly")
32+
YOUTUBE_ANALYTICS_API_SERVICE_NAME = "youtubeAnalytics"
33+
YOUTUBE_ANALYTICS_API_VERSION = "v1beta1"
34+
35+
# This variable defines a message to display if the CLIENT_SECRETS_FILE is
36+
# missing.
37+
MISSING_CLIENT_SECRETS_MESSAGE = """
38+
WARNING: Please configure OAuth 2.0
39+
40+
To make this sample run you will need to populate the client_secrets.json file
41+
found at:
42+
43+
%s
44+
45+
with information from the Cloud Console
46+
https://cloud.google.com/console
47+
48+
For more information about the client_secrets.json file format, please visit:
49+
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
50+
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
51+
CLIENT_SECRETS_FILE))
52+
53+
# Maps a shorthand notation for the different report types to the string used
54+
# to identify each type in the batchReportDefinitionList response.
55+
REPORT_TYPES_TO_NAMES = dict(
56+
assets="Full asset report",
57+
claims="Full claim report"
58+
)
59+
60+
def get_authenticated_service(args):
61+
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,
62+
scope=" ".join(SCOPES),
63+
message=MISSING_CLIENT_SECRETS_MESSAGE)
64+
65+
storage = Storage("%s-oauth2.json" % sys.argv[0])
66+
credentials = storage.get()
67+
68+
if credentials is None or credentials.invalid:
69+
credentials = run_flow(flow, storage, args)
70+
71+
http = credentials.authorize(httplib2.Http())
72+
73+
return build(YOUTUBE_ANALYTICS_API_SERVICE_NAME,
74+
YOUTUBE_ANALYTICS_API_VERSION, http=http)
75+
76+
def get_available_reports(youtubeAnalytics, contentOwner):
77+
definitions_list_response = youtubeAnalytics.batchReportDefinitions().list(
78+
onBehalfOfContentOwner=contentOwner,
79+
).execute()
80+
81+
return definitions_list_response["items"]
82+
83+
def get_info_for_report(youtubeAnalytics, contentOwner, report_id):
84+
reports_list_response = youtubeAnalytics.batchReports().list(
85+
onBehalfOfContentOwner=contentOwner,
86+
batchReportDefinitionId=report_id
87+
).execute()
88+
89+
url = reports_list_response["items"][0]["outputs"][0]["downloadUrl"]
90+
date = reports_list_response["items"][0]["timeSpan"]["startTime"]
91+
return (url, date)
92+
93+
if __name__ == "__main__":
94+
argparser.add_argument("--content-owner-id", required=True,
95+
help="ID of the content owner.")
96+
argparser.add_argument("--report-type", required=True,
97+
choices=REPORT_TYPES_TO_NAMES.keys(), help="The type of report to download.")
98+
argparser.add_argument("--download-directory", default=os.getcwd(),
99+
help="The directory to download the report into.")
100+
args = argparser.parse_args()
101+
102+
# Steps to download a batch report:
103+
# 1. Given an authorized instance of the YouTube Analytics service, retrieve
104+
# a list of all the available report definitions via
105+
# youtubeAnalytics.batchReportDefinitions.list()
106+
# 2. Iterate through the report definitions to find the one we're interested
107+
# in based on its name: either an assets or claims report.
108+
# 3. Get the unique id of the report definition, which will in turn be passed
109+
# in to youtubeAnalytics.batchReports.list().
110+
# 4. The youtubeAnalytics.batchReports.list() reponse will contain one or more
111+
# days' worth of reports. The code gets download info for the first item
112+
# in the response, which will be the most recent day's report.
113+
# 5. Parse out the date and the download URL for the relevant report, and use
114+
# that to download the report, with the date used as part of the file name.
115+
youtubeAnalytics = get_authenticated_service(args)
116+
try:
117+
reports = get_available_reports(youtubeAnalytics, args.content_owner_id)
118+
119+
report_id = None
120+
for report in reports:
121+
if (REPORT_TYPES_TO_NAMES[args.report_type] == report["name"]
122+
and report["status"] == "supported"):
123+
report_id = report["id"]
124+
break
125+
126+
if report_id:
127+
(url, date) = get_info_for_report(youtubeAnalytics,
128+
args.content_owner_id, report_id)
129+
130+
file_path = os.path.join(args.download_directory,
131+
"%s-%s.csv" % (args.report_type, date))
132+
133+
# This is a simple approach to downloading a file at a given URL.
134+
# If desired, you can add in a callback method to log the
135+
# progress of the download. See
136+
# http://docs.python.org/2/library/urllib.html#urllib.urlretrieve
137+
urllib.urlretrieve(url, file_path)
138+
139+
print "The report was downloaded to %s" % file_path
140+
else:
141+
# There might not be a report available if, for instance, there are no
142+
# assets or claims associated with a given content owner's account.
143+
print "No report of type '%s' was available." % args.report_type
144+
except HttpError, e:
145+
print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)

0 commit comments

Comments
 (0)