YouTube Reporting API - Get Bulk Data Reports

YouTube Reporting API は、チャンネルまたはコンテンツ所有者の YouTube アナリティクスの包括的なデータセットを含む事前定義レポートをサポートしています。これらのレポートでは、YouTube アナリティクス API または YouTube Studio の [アナリティクス] セクションでクエリを実行できる一括データセットをダウンロードできます。

この API は、自動生成された一連のシステム管理レポートもサポートしています。これらのレポートは、[レポート] メニューで対応するレポートにアクセスできるコンテンツ所有者が利用できます。これらのレポートには、広告収入データと YouTube Premium サブスクリプション収益データが含まれます。詳細については、システム管理レポートのドキュメントをご覧ください。

概要

これらのレポートのレポート フィールドは、ディメンションまたは指標のいずれかです。

  • ディメンションは、データの集計に使用される一般的な条件です。たとえば、アクションが発生した日付や、ユーザーが居住している国などです。レポートの各行には、ディメンション値の一意の組み合わせがあります。
  • 指標は、ユーザー アクティビティ、広告のパフォーマンス、推定収益に関連する個々の測定値です。ユーザー アクティビティの指標には、動画の視聴回数や評価(高評価と低評価)などがあります。

たとえば、チャンネルの基本的なユーザー アクティビティ レポートには、次のディメンションが含まれます。

  • day: アクティビティが発生した日付。
  • channel: アクティビティに関連付けられている YouTube チャンネル。
  • video: アクティビティに関連付けられた YouTube 動画。
  • liveOrOnDemand: 視聴者がライブ動画配信を視聴していたかどうかを示す値。
  • subscribedStatus: 視聴者がチャンネルに登録しているかどうかを示す値。
  • country: 視聴者の居住国。

レポートには、視聴回数高評価averageViewDurationなど、多くの指標も含まれています。レポートを取得してインポートした後、アプリケーションは共通のディメンション値に基づいてさまざまな計算を行うことができます。

たとえば、特定の日付のドイツでの視聴回数の合計を計算するには、country 列の値が DE で、day 列の値が YYYY-MM-DD 形式の日付であるすべての行の [views] 指標の値を合計します。

YouTube アナリティクス レポートを取得する

次の手順では、API を使用してチャンネルとコンテンツ所有者のレポートを取得する方法について説明します。これらのレポートを取得する方法については、システム管理レポートをご覧ください。

ステップ 1: 認可認証情報を取得する

YouTube Reporting API のすべてのリクエストは承認を受ける必要があります。OAuth 2.0 プロトコルを使用して認可トークンを取得するには、認可ガイドをご覧ください。

YouTube Reporting API リクエストでは、次の認可スコープが使用されます。

スコープ
https://www.googleapis.com/auth/yt-analytics.readonly YouTube コンテンツの YouTube アナリティクス レポートを表示します。このスコープは再生回数や評価数など、ユーザー アクティビティの指標へのアクセスを提供します。
https://www.googleapis.com/auth/yt-analytics-monetary.readonly YouTube コンテンツに関する YouTube アナリティクス収益レポートを表示します。このスコープでは、ユーザー アクティビティの指標、推定収益と広告パフォーマンスの指標にアクセスできます。

ステップ 2: 取得するレポートを特定する

API の reportTypes.list メソッドを呼び出して、チャンネルまたはコンテンツ所有者に対して生成できるレポートのリストを取得します。このメソッドは、レポート ID と名前のリストを返します。生成するレポートの id プロパティ値を取得します。たとえば、チャンネルの基本的なユーザー アクティビティ レポートの ID は channel_basic_a3 です。

レポート名は、サポートされているチャンネル レポートコンテンツ所有者レポートを定義するドキュメントでも確認できます。

ステップ 3: レポートジョブを作成する

レポートのレポート作成ジョブを作成しないと、レポートの生成は開始されません。(そのため、レポートは、実際にレポートを取得するチャンネルとコンテンツ所有者のみが生成します)。

レポート作成ジョブを作成するには、API の jobs.create メソッドを呼び出します。リクエスト本文に次の値を設定します。

  • reportTypeId プロパティの値を、手順 2 で取得したレポート ID に設定します。
  • name プロパティの値を、レポートに関連付ける名前に設定します。

jobs.create メソッドに対する API レスポンスには、ジョブを一意に識別する ID を指定する Job リソースが含まれています。レポートの取得は、ジョブの作成から 48 時間以内に開始できます。最初に利用できるレポートは、ジョブのスケジュール設定日に関するレポートです。

たとえば、9 月 1 日にジョブをスケジュールすると、9 月 1 日のレポートは 9 月 3 日に準備されます。9 月 2 日のレポートは 9 月 4 日に投稿されます。

ステップ 4: ジョブ ID を取得する

注: 手順 3 で返されたジョブ ID をアプリケーションが保存している場合は、この手順をスキップできます。

jobs.list メソッドを呼び出して、スケジュールされたジョブのリストを取得します。返された各 Job リソースの reportTypeId プロパティは、そのジョブが生成したレポートのタイプを示します。次のステップで、同じリソースの id プロパティ値がアプリケーションに必要になります。

ステップ 5: レポートのダウンロード URL を取得する

jobs.reports.list メソッドを呼び出して、ジョブ用に作成されたレポートのリストを取得します。リクエストで、jobId パラメータを取得するレポートのジョブ ID に設定します。

ヒント: createdAfter パラメータを使用して、指定した時刻以降に作成されたレポートのみを API が返すように指定します。このパラメータを使用すると、まだ処理していないレポートのみを API から返すようにできます。

API レスポンスには、そのジョブの Report リソースのリストが含まれます。各リソースは、一意の 24 時間の期間のデータを含むレポートを参照します。なお、データが取得できなかった日についても、ダウンロード可能なレポートが生成されます。これらのレポートにはヘッダー行はありますが、追加のデータは含まれていません。

  • リソースの startTime プロパティと endTime プロパティは、レポートのデータが対象とする期間を識別します。
  • リソースの downloadUrl プロパティは、レポートを取得できる URL を識別します。
  • リソースの createTime プロパティには、レポートが生成された日時を指定します。アプリはこの値を保存し、以前にダウンロードしたレポートが変更されたかどうかを判断するために使用する必要があります。

ステップ 6: レポートをダウンロードする

ステップ 5 で取得した downloadUrl に HTTP GET リクエストを送信して、レポートを取得します。

ダウンロード リクエストで gzip 圧縮を有効にすると、レポートのダウンロードに必要な帯域幅を削減できます。API レスポンスの解凍には追加の CPU 時間が必要になりますが、ネットワーク リソースの消費量低下には、そのコストを補うだけの利点があります。

gzip でエンコードされたレスポンスを受信するには、次の例に示すように、Accept-Encoding HTTP リクエスト ヘッダーを gzip に設定します。

Accept-Encoding: gzip

処理レポート

ベスト プラクティス

YouTube Reporting API を使用するアプリは、常に以下のプラクティスに従う必要があります。

  • レポートの列の順序を決定するには、レポートのヘッダー行を使用します。たとえば、レポートの説明に最初に記載されている指標が視聴回数だからといって、レポートで最初に返される指標が視聴回数になるとは限りません。代わりに、レポートのヘッダー行を使用して、そのデータを含む列を特定します。

  • レポート処理を将来にわたって対応できるようにするには、レポートに新しい指標が追加されることを想定し、新しい列が追加されたときに処理して組み込む準備をしておくことが重要です。新しい指標は、レポートのヘッダーに新しい列として表示されます。

  • 同じレポートを繰り返し処理しないように、ダウンロードしたレポートを記録しておいてください。次のリストに、その方法をいくつか示します。

    • reports.list メソッドを呼び出すときに、createdAfter パラメータを使用して、特定の日付以降に作成されたレポートのみを取得します。(初めてレポートを取得する場合は、createdAfter パラメータを省略します)。

      レポートを取得して正常に処理するたびに、最新のレポートが作成された日時に対応するタイムスタンプを保存します。次に、reports.list メソッドを呼び出すたびに createdAfter パラメータ値を更新して、API を呼び出すたびに新しいレポート(バックフィルされたデータを含む新しいレポートを含む)のみを取得するようにします。

      安全のため、レポートを取得する前に、レポートの ID がデータベースにまだ登録されていないことを確認してください。

    • ダウンロードして処理した各レポートの ID を保存します。また、各レポートが生成された日時や、レポートの startTimeendTime(レポートにデータが含まれる期間を特定する)などの追加情報を保存することもできます。各レポートには 24 時間分の情報が含まれているため、各ジョブには多くのレポートが生成される可能性があります。

      レポート ID を使用して、まだダウンロードしてインポートする必要があるレポートを特定します。ただし、2 つの新しいレポートの startTime プロパティ値と endTime プロパティ値が同じ場合は、新しい createTime 値を持つレポートのみがインポートされます。

  • レポートには、YouTube リソースに関連付けられた ID が含まれます。これらのリソースの追加メタデータを取得するには、YouTube Data API を使用します。YouTube API サービスのデベロッパー ポリシー(III.E.4.b ~ III.E.4.d セクション)に記載されているように、API クライアントは 30 日後に、その API から保存されているリソース メタデータを削除するか、更新する必要があります。

レポートの特性

API レポートは、次の特性を持つバージョン管理された .csv(カンマ区切りの値)ファイルです。

  • 各レポートには、太平洋標準時(UTC-8)の午前 0 時から午後 11 時 59 分までの 24 時間の独自の期間のデータが含まれます。そのため、どのレポートでも、ディメンションの値は常に同じです。

  • レポートは毎日更新されます。

  • データが利用できなかった日についても、ダウンロード可能なレポートが生成されます。これらのレポートにはヘッダー行は含まれますが、追加のデータは含まれません。

  • API レポートは、生成後 60 日間利用できます(新しいレポート作成ジョブで生成された過去のデータは除きます)。レポートは、作成から 60 日が経過するとアクセスできなくなります。
  • 過去のデータを含むレポートは、生成後 30 日間利用できます。履歴データを含むレポートは、30 日経過するとアクセスできなくなります。
  • レポートデータはフィルタされません。そのため、チャンネル レポートには、削除されたリソースに関連する次の段落に記載されているものを除き、チャンネルの動画または再生リストのすべてのデータが含まれます。同様に、コンテンツ所有者レポートには、コンテンツ所有者のチャンネルに関するすべてのデータ(動画、再生リスト、広告のパフォーマンスなど)が含まれますが、次の例外があります。

    レポートのデータはフィルタされませんが、レポートには、レポートの生成日から 30 日前より前に削除された YouTube リソースへの参照は含まれません。

  • レポートデータが並べ替えられていない。

  • レポートでは、指標がない行は省略されます。つまり、指標がない行はレポートから除外されます。たとえば、特定の日にアルバニアで動画の視聴回数が 0 回だった場合、その日のレポートにはアルバニアの行は含まれません。

  • レポートには、チャンネルのすべての動画の合計視聴回数など、指標の概要データを提供する行は含まれません。これらの合計値は、レポート内の値の合計として計算できますが、削除された動画の指標が含まれない場合があります。YouTube Analytics API を使用して合計数を取得することもできます。YouTube Analytics API は、削除されたリソースの指標を含む合計値を返します。ただし、そのリソースは API レスポンスで明示的に参照されません。

データをバックフィルする

バックフィル データとは、以前に配信されたセットに代わるデータセットを指します。バックフィル データ レポートが利用可能になったら、アプリは新しいレポートを取得し、保存されているデータを更新して、修正されたデータセットと一致させる必要があります。たとえば、アプリケーションでレポートの対象期間の以前のデータを削除してから、新しいデータセットをインポートできます。

YouTube にバックフィル データがある場合は、新しいレポート ID を持つ新しいレポートが生成されます。その場合、レポートの startTime プロパティ値と endTime プロパティ値は、以前に利用可能で、以前にダウンロードした可能性のあるレポートの開始時間と終了時間と一致します。

バックフィル レポートには、レポートの生成日から 30 日前より前に削除された YouTube リソースへの参照は含まれません。

過去のデータ

新しいレポート作成ジョブをスケジュールすると、その日から過去のレポートが生成され、ジョブの作成日より前の 30 日間にわたるレポートが生成されます。したがって、このドキュメントでは、過去のデータとは、レポートジョブのスケジュール設定前の期間のデータを含むレポートを指します。

履歴レポートは、利用可能になり次第公開されます。通常、ジョブの過去のデータはすべて数日以内に投稿されます。レポートの特性セクションで説明したように、履歴データを含むレポートは、生成後 30 日間利用できます。履歴データ以外のデータを含むレポートは、60 日間利用できます。

データの匿名化

YouTube 視聴者の匿名性を維持するため、一部のディメンションの値は、同じ行の指標が特定のしきい値を満たした場合にのみ返されます。

たとえば、チャネルの動画トラフィック ソース レポートの各行には、trafficSourceTypetrafficSourceDetail など、複数のディメンションが含まれています。各行には、視聴回数などのさまざまな指標も含まれています。YouTube 検索から発生したトラフィックを示す行では、trafficSourceDetail ディメンションに、トラフィックを誘導した検索語句が示されます。

この例では、次のルールが適用されます。

  • トラフィック ソース レポートでは、特定の日に特定の動画の視聴回数が一定数に達した場合にのみ、クエリキーワード(trafficSourceDetail)が特定されます。この場合、[視聴回数] が指標、[動画] が集計ディメンション、[trafficSourceDetail] が匿名化ディメンションです。

  • レポートには、視聴回数しきい値を満たさないすべての trafficSourceDetail 値の指標を集計した行が追加されます。この行には、これらの検索語句に関連付けられた視聴回数の合計が表示されますが、語句自体は特定されません。

次の表に、これらのルールを示します。最初の表には、YouTube がトラフィック ソース レポートの生成に使用する架空の一連の元データが含まれ、2 番目の表にはレポート自体が含まれます。この例では、視聴回数のしきい値が 10 に設定されているため、特定の日に特定の動画の視聴回数が 10 回以上だった検索語句のみがレポートに表示されます。(実際のしきい値は変更される可能性があります)。

動画の YouTube 検索トラフィックの元データ

次のデータは、特定の日に特定の動画に対して発生した YouTube 検索トラフィックを表しているとします。

検索語句 視聴回数 推定再生時間(分)
江南スタイル 100 200
psy 15 25
psy gangnam 9 15
oppa gangnam 5 8
乗馬ダンス 2 5

トラフィック ソース レポートのサンプル

次の表は、前のセクションの元データに対して YouTube が生成したトラフィック ソース レポートの抜粋です。(実際のレポートには、より多くのディメンションと指標が含まれます)。この例では、10 回以上の視聴につながった検索語句のみがレポートに表示されます。実際のしきい値は変更される可能性があります。

レポートの 3 行目では、trafficSourceDetail ディメンションの値は NULL です。views 指標と estimatedMinutesWatched 指標には、視聴回数が 10 回未満だった 3 つの検索語句の合計視聴回数と合計再生時間が含まれます。

trafficSourceDetail 視聴回数 estimatedMinutesWatched
江南スタイル 100 200
psy 15 25
NULL 16 28

匿名化の対象となるディメンション

次の表に、関連する指標値が特定のしきい値を満たさない場合に匿名化されるディメンション値を示します。いずれの場合も、指標の値は別のディメンションで集計されます。たとえば、指標が視聴回数で、集計項目が動画の場合、動画が一定回数視聴されていない限り、項目値は匿名化されます。

指標 集計ディメンション 匿名化されたディメンション 匿名化された値
subscribersGained channel country ZZ
subscribersGained channel province US-ZZ
subscribersLost channel country ZZ
subscribersLost channel province US-ZZ
comments video country ZZ
comments video province US-ZZ
高評価 video country ZZ
高評価 video province US-ZZ
低評価 video country ZZ
低評価 video province US-ZZ
視聴回数 video ageGroup NULL
視聴回数 video gender NULL
視聴回数 videotrafficSourceDetail trafficSourceDetail NULL
チャンネル登録者数 channel subscribedStatus NULL

コードサンプル

次のコードサンプルは、API を使用してレポート ジョブを作成し、そのジョブのレポートを取得する方法を示しています。各言語に 2 つのコードサンプルが用意されています。

  1. 最初のコードサンプルは、使用可能なレポートタイプのリストを取得して、新しいレポートジョブを作成する方法を示しています。

  2. 2 つ目のコードサンプルは、特定のジョブのレポートを取得する方法を示しています。ジョブの作成から 48 時間以内にレポートの取得を開始できます。

注: 次のコードサンプルは、サポートされているプログラミング言語のすべてを網羅しているわけではありません。サポートされている言語の一覧については、クライアント ライブラリをご覧ください。

Java

次のサンプルでは、Java クライアント ライブラリを使用します。

例 1: レポートジョブを作成する

次のコードサンプルは、reportTypes.list メソッドを呼び出して、使用可能なレポートタイプのリストを取得します。次に、jobs.create メソッドを呼び出して新しいレポートジョブを作成します。

/*  * Copyright (c) 2015 Google Inc.  *  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except  * in compliance with the License. You may obtain a copy of the License at  *  * http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software distributed under the License  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express  * or implied. See the License for the specific language governing permissions and limitations under  * the License.  */  package com.google.api.services.samples.youtube.cmdline.reporting;  import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.services.samples.youtube.cmdline.Auth; import com.google.api.services.youtubereporting.YouTubeReporting; import com.google.api.services.youtubereporting.model.Job; import com.google.api.services.youtubereporting.model.ListReportTypesResponse; import com.google.api.services.youtubereporting.model.ReportType; import com.google.common.collect.Lists;  import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.List;  /**  * This sample creates a reporting job by:  *  * 1. Listing the available report types using the "reportTypes.list" method.  * 2. Creating a reporting job using the "jobs.create" method.  *  * @author Ibrahim Ulukaya  */ public class CreateReportingJob {      /**      * Define a global instance of a YouTube Reporting object, which will be used to make      * YouTube Reporting API requests.      */     private static YouTubeReporting youtubeReporting;       /**      * Create a reporting job.      *      * @param args command line args (not used).      */     public static void main(String[] args) {          /*          * This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for          * authenticated user's account. Any request that retrieves earnings or ad performance metrics must          * use this scope.          */         List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/yt-analytics-monetary.readonly");          try {             // Authorize the request.             Credential credential = Auth.authorize(scopes, "createreportingjob");              // This object is used to make YouTube Reporting API requests.             youtubeReporting = new YouTubeReporting.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)                     .setApplicationName("youtube-cmdline-createreportingjob-sample").build();              // Prompt the user to specify the name of the job to be created.             String name = getNameFromUser();              if (listReportTypes()) {               createReportingJob(getReportTypeIdFromUser(), name);             }         } catch (GoogleJsonResponseException e) {             System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode()                     + " : " + e.getDetails().getMessage());             e.printStackTrace();          } catch (IOException e) {             System.err.println("IOException: " + e.getMessage());             e.printStackTrace();         } catch (Throwable t) {             System.err.println("Throwable: " + t.getMessage());             t.printStackTrace();         }     }      /**      * Lists report types. (reportTypes.listReportTypes)      * @return true if at least one report type exists      * @throws IOException      */     private static boolean listReportTypes() throws IOException {         // Call the YouTube Reporting API's reportTypes.list method to retrieve report types.         ListReportTypesResponse reportTypesListResponse = youtubeReporting.reportTypes().list()             .execute();         List<ReportType> reportTypeList = reportTypesListResponse.getReportTypes();          if (reportTypeList == null || reportTypeList.isEmpty()) {           System.out.println("No report types found.");           return false;         } else {             // Print information from the API response.             System.out.println("\n================== Report Types ==================\n");             for (ReportType reportType : reportTypeList) {                 System.out.println("  - Id: " + reportType.getId());                 System.out.println("  - Name: " + reportType.getName());                 System.out.println("\n-------------------------------------------------------------\n");            }         }         return true;     }      /**      * Creates a reporting job. (jobs.create)      *      * @param reportTypeId Id of the job's report type.      * @param name name of the job.      * @throws IOException      */     private static void createReportingJob(String reportTypeId, String name)         throws IOException {         // Create a reporting job with a name and a report type id.         Job job = new Job();         job.setReportTypeId(reportTypeId);         job.setName(name);          // Call the YouTube Reporting API's jobs.create method to create a job.         Job createdJob = youtubeReporting.jobs().create(job).execute();          // Print information from the API response.         System.out.println("\n================== Created reporting job ==================\n");         System.out.println("  - ID: " + createdJob.getId());         System.out.println("  - Name: " + createdJob.getName());         System.out.println("  - Report Type Id: " + createdJob.getReportTypeId());         System.out.println("  - Create Time: " + createdJob.getCreateTime());         System.out.println("\n-------------------------------------------------------------\n");     }      /*      * Prompt the user to enter a name for the job. Then return the name.      */     private static String getNameFromUser() throws IOException {          String name = "";          System.out.print("Please enter the name for the job [javaTestJob]: ");         BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));         name = bReader.readLine();          if (name.length() < 1) {             // If nothing is entered, defaults to "javaTestJob".           name = "javaTestJob";         }          System.out.println("You chose " + name + " as the name for the job.");         return name;     }      /*      * Prompt the user to enter a report type id for the job. Then return the id.      */     private static String getReportTypeIdFromUser() throws IOException {          String id = "";          System.out.print("Please enter the reportTypeId for the job: ");         BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));         id = bReader.readLine();          System.out.println("You chose " + id + " as the report type Id for the job.");         return id;     } } 

例 2: レポートを取得する

このコードサンプルでは、jobs.list メソッドを呼び出してレポート ジョブのリストを取得します。次に、jobId パラメータを特定のジョブ ID に設定して reports.list メソッドを呼び出し、そのジョブによって作成されたレポートを取得します。最後に、各レポートのダウンロード URL が印刷されます。

/*  * Copyright (c) 2015 Google Inc.  *  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except  * in compliance with the License. You may obtain a copy of the License at  *  * http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software distributed under the License  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express  * or implied. See the License for the specific language governing permissions and limitations under  * the License.  */  package com.google.api.services.samples.youtube.cmdline.reporting;  import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.GenericUrl; import com.google.api.services.samples.youtube.cmdline.Auth; import com.google.api.services.youtubereporting.YouTubeReporting; import com.google.api.services.youtubereporting.YouTubeReporting.Media.Download; import com.google.api.services.youtubereporting.model.Job; import com.google.api.services.youtubereporting.model.ListJobsResponse; import com.google.api.services.youtubereporting.model.ListReportsResponse; import com.google.api.services.youtubereporting.model.Report;  import com.google.common.collect.Lists;  import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.List;  import javax.print.attribute.standard.Media;  /**  * This sample retrieves reports created by a specific job by:  *  * 1. Listing the jobs using the "jobs.list" method.  * 2. Retrieving reports using the "reports.list" method.  *  * @author Ibrahim Ulukaya  */ public class RetrieveReports {      /**      * Define a global instance of a YouTube Reporting object, which will be used to make      * YouTube Reporting API requests.      */     private static YouTubeReporting youtubeReporting;       /**      * Retrieve reports.      *      * @param args command line args (not used).      */     public static void main(String[] args) {          /*          * This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for          * authenticated user's account. Any request that retrieves earnings or ad performance metrics must          * use this scope.          */         List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/yt-analytics-monetary.readonly");          try {             // Authorize the request.             Credential credential = Auth.authorize(scopes, "retrievereports");              // This object is used to make YouTube Reporting API requests.             youtubeReporting = new YouTubeReporting.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)                     .setApplicationName("youtube-cmdline-retrievereports-sample").build();              if (listReportingJobs()) {               if(retrieveReports(getJobIdFromUser())) {                 downloadReport(getReportUrlFromUser());               }             }         } catch (GoogleJsonResponseException e) {             System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode()                     + " : " + e.getDetails().getMessage());             e.printStackTrace();          } catch (IOException e) {             System.err.println("IOException: " + e.getMessage());             e.printStackTrace();         } catch (Throwable t) {             System.err.println("Throwable: " + t.getMessage());             t.printStackTrace();         }     }      /**      * Lists reporting jobs. (jobs.listJobs)      * @return true if at least one reporting job exists      * @throws IOException      */     private static boolean listReportingJobs() throws IOException {         // Call the YouTube Reporting API's jobs.list method to retrieve reporting jobs.         ListJobsResponse jobsListResponse = youtubeReporting.jobs().list().execute();         List<Job> jobsList = jobsListResponse.getJobs();          if (jobsList == null || jobsList.isEmpty()) {           System.out.println("No jobs found.");           return false;         } else {             // Print information from the API response.             System.out.println("\n================== Reporting Jobs ==================\n");             for (Job job : jobsList) {                 System.out.println("  - Id: " + job.getId());                 System.out.println("  - Name: " + job.getName());                 System.out.println("  - Report Type Id: " + job.getReportTypeId());                 System.out.println("\n-------------------------------------------------------------\n");             }         }         return true;     }      /**      * Lists reports created by a specific job. (reports.listJobsReports)      *      * @param jobId The ID of the job.      * @throws IOException      */     private static boolean retrieveReports(String jobId)         throws IOException {         // Call the YouTube Reporting API's reports.list method         // to retrieve reports created by a job.         ListReportsResponse reportsListResponse = youtubeReporting.jobs().reports().list(jobId).execute();         List<Report> reportslist = reportsListResponse.getReports();          if (reportslist == null || reportslist.isEmpty()) {             System.out.println("No reports found.");             return false;         } else {             // Print information from the API response.             System.out.println("\n============= Reports for the job " + jobId + " =============\n");             for (Report report : reportslist) {                 System.out.println("  - Id: " + report.getId());                 System.out.println("  - From: " + report.getStartTime());                 System.out.println("  - To: " + report.getEndTime());                 System.out.println("  - Download Url: " + report.getDownloadUrl());                 System.out.println("\n-------------------------------------------------------------\n");             }         }         return true;     }      /**      * Download the report specified by the URL. (media.download)      *      * @param reportUrl The URL of the report to be downloaded.      * @throws IOException      */     private static boolean downloadReport(String reportUrl)         throws IOException {         // Call the YouTube Reporting API's media.download method to download a report.         Download request = youtubeReporting.media().download("");         FileOutputStream fop = new FileOutputStream(new File("report"));         request.getMediaHttpDownloader().download(new GenericUrl(reportUrl), fop);         return true;     }      /*      * Prompt the user to enter a job id for report retrieval. Then return the id.      */     private static String getJobIdFromUser() throws IOException {          String id = "";          System.out.print("Please enter the job id for the report retrieval: ");         BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));         id = bReader.readLine();          System.out.println("You chose " + id + " as the job Id for the report retrieval.");         return id;     }      /*      * Prompt the user to enter a URL for report download. Then return the URL.      */     private static String getReportUrlFromUser() throws IOException {          String url = "";          System.out.print("Please enter the report URL to download: ");         BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));         url = bReader.readLine();          System.out.println("You chose " + url + " as the URL to download.");         return url;     }}  

PHP

次のサンプルでは、PHP クライアント ライブラリを使用します。

例 1: レポートジョブを作成する

次のコードサンプルは、reportTypes.list メソッドを呼び出して、使用可能なレポートタイプのリストを取得します。次に、jobs.create メソッドを呼び出して新しいレポートジョブを作成します。

<?php  /**  * This sample creates a reporting job by:  *  * 1. Listing the available report types using the "reportTypes.list" method.  * 2. Creating a reporting job using the "jobs.create" method.  *  * @author Ibrahim Ulukaya  */  /**  * Library Requirements  *  * 1. Install composer (https://getcomposer.org)  * 2. On the command line, change to this directory (api-samples/php)  * 3. Require the google/apiclient library  *    $ composer require google/apiclient:~2.0  */ if (!file_exists(__DIR__ . '/vendor/autoload.php')) {   throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"'); }  require_once __DIR__ . '/vendor/autoload.php'; session_start();  /*  * You can acquire an OAuth 2.0 client ID and client secret from the  * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>  * For more information about using OAuth 2.0 to access Google APIs, please see:  * <https://developers.google.com/youtube/v3/guides/authentication>  * Please ensure that you have enabled the YouTube Data API for your project.  */ $OAUTH2_CLIENT_ID = 'REPLACE_ME'; $OAUTH2_CLIENT_SECRET = 'REPLACE_ME';  $client = new Google_Client(); $client->setClientId($OAUTH2_CLIENT_ID); $client->setClientSecret($OAUTH2_CLIENT_SECRET);  /*  * This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for  * authenticated user's account. Any request that retrieves earnings or ad performance metrics must  * use this scope.  */ $client->setScopes('https://www.googleapis.com/auth/yt-analytics-monetary.readonly'); $redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],     FILTER_SANITIZE_URL); $client->setRedirectUri($redirect);  // YouTube Reporting object used to make YouTube Reporting API requests. $youtubeReporting = new Google_Service_YouTubeReporting($client);  // Check if an auth token exists for the required scopes $tokenSessionKey = 'token-' . $client->prepareScopes(); if (isset($_GET['code'])) {   if (strval($_SESSION['state']) !== strval($_GET['state'])) {     die('The session state did not match.');   }    $client->authenticate($_GET['code']);   $_SESSION[$tokenSessionKey] = $client->getAccessToken();   header('Location: ' . $redirect); }  if (isset($_SESSION[$tokenSessionKey])) {   $client->setAccessToken($_SESSION[$tokenSessionKey]); }  // Check to ensure that the access token was successfully acquired. if ($client->getAccessToken()) {   // This code executes if the user enters a name in the form   // and submits the form. Otherwise, the page displays the form above.   try {     if (empty(listReportTypes($youtubeReporting, $htmlBody))) {       $htmlBody .= sprintf('<p>No report types found.</p>');     } else if ($_GET['reportTypeId']){       createReportingJob($youtubeReporting, $_GET['reportTypeId'], $_GET['jobName'], $htmlBody);     }   } catch (Google_Service_Exception $e) {     $htmlBody = sprintf('<p>A service error occurred: <code>%s</code></p>',         htmlspecialchars($e->getMessage()));   } catch (Google_Exception $e) {     $htmlBody = sprintf('<p>An client error occurred: <code>%s</code></p>',         htmlspecialchars($e->getMessage()));   }   $_SESSION[$tokenSessionKey] = $client->getAccessToken(); } elseif ($OAUTH2_CLIENT_ID == 'REPLACE_ME') {   $htmlBody = <<<END   <h3>Client Credentials Required</h3>   <p>     You need to set <code>\$OAUTH2_CLIENT_ID</code> and     <code>\$OAUTH2_CLIENT_ID</code> before proceeding.   <p> END; } else {   // If the user hasn't authorized the app, initiate the OAuth flow   $state = mt_rand();   $client->setState($state);   $_SESSION['state'] = $state;    $authUrl = $client->createAuthUrl();   $htmlBody = <<<END   <h3>Authorization Required</h3>   <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p> END; }   /**  * Creates a reporting job. (jobs.create)  *  * @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.  * @param string $reportTypeId Id of the job's report type.  * @param string $name name of the job.  * @param $htmlBody - html body.  */ function createReportingJob(Google_Service_YouTubeReporting $youtubeReporting, $reportTypeId,     $name, &$htmlBody) {   # Create a reporting job with a name and a report type id.   $reportingJob = new Google_Service_YouTubeReporting_Job();   $reportingJob->setReportTypeId($reportTypeId);   $reportingJob->setName($name);    // Call the YouTube Reporting API's jobs.create method to create a job.   $jobCreateResponse = $youtubeReporting->jobs->create($reportingJob);    $htmlBody .= "<h2>Created reporting job</h2><ul>";   $htmlBody .= sprintf('<li>"%s" for reporting type "%s" at "%s"</li>',       $jobCreateResponse['name'], $jobCreateResponse['reportTypeId'], $jobCreateResponse['createTime']);   $htmlBody .= '</ul>'; }   /**  * Returns a list of report types. (reportTypes.listReportTypes)  *  * @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.  * @param $htmlBody - html body.  */ function listReportTypes(Google_Service_YouTubeReporting $youtubeReporting, &$htmlBody) {   // Call the YouTube Reporting API's reportTypes.list method to retrieve report types.   $reportTypes = $youtubeReporting->reportTypes->listReportTypes();    $htmlBody .= "<h3>Report Types</h3><ul>";   foreach ($reportTypes as $reportType) {     $htmlBody .= sprintf('<li>id: "%s", name: "%s"</li>', $reportType['id'], $reportType['name']);   }   $htmlBody .= '</ul>';    return $reportTypes; } ?>  <!doctype html> <html> <head> <title>Create a reporting job</title> </head> <body>   <form method="GET">     <div>       Job Name: <input type="text" id="jobName" name="jobName" placeholder="Enter Job Name">     </div>     <br>     <div>       Report Type Id: <input type="text" id="reportTypeId" name="reportTypeId" placeholder="Enter Report Type Id">     </div>     <br>     <input type="submit" value="Create!">   </form>   <?=$htmlBody?> </body> </html> 

例 2: レポートを取得する

このコードサンプルでは、jobs.list メソッドを呼び出してレポート ジョブのリストを取得します。次に、jobId パラメータを特定のジョブ ID に設定して reports.list メソッドを呼び出し、そのジョブによって作成されたレポートを取得します。最後に、各レポートのダウンロード URL が印刷されます。

<?php  /**  * This sample supports the following use cases:  *  * 1. Retrieve reporting jobs by content owner:  *    Ex: php retrieve_reports.php  --contentOwner=="CONTENT_OWNER_ID"  *    Ex: php retrieve_reports.php  --contentOwner=="CONTENT_OWNER_ID" --includeSystemManaged==True  * 2. Retrieving list of downloadable reports for a particular job:  *    Ex: php retrieve_reports.php  --contentOwner=="CONTENT_OWNER_ID" --jobId="JOB_ID"  * 3. Download a report:  *    Ex: php retrieve_reports.php  --contentOwner=="CONTENT_OWNER_ID" --downloadUrl="DOWNLOAD_URL" --outputFile="report.txt"  */  /**  * Library Requirements  *  * 1. Install composer (https://getcomposer.org)  * 2. On the command line, change to this directory (api-samples/php)  * 3. Require the google/apiclient library  *    $ composer require google/apiclient:~2.0  */ if (!file_exists(__DIR__ . '/vendor/autoload.php')) {   throw new \Exception('please run "composer require google/apiclient:~2.2.0" in "' . __DIR__ .'"'); }  require_once __DIR__ . '/vendor/autoload.php'; session_start();   define('CREDENTIALS_PATH', '~/.credentials/youtube-php.json');  $longOptions = array(   'contentOwner::',   'downloadUrl::',   'includeSystemManaged::',   'jobId::',   'outputFile::', );  $options = getopt('', $longOptions);  $CONTENT_OWNER_ID = ($options['contentOwner'] ? $options['contentOwner'] : ''); $DOWNLOAD_URL = (array_key_exists('downloadUrl', $options) ?                  $options['downloadUrl'] : ''); $INCLUDE_SYSTEM_MANAGED = (array_key_exists('includeSystemManaged', $options) ?                            $options['includeSystemManaged'] : ''); $JOB_ID = (array_key_exists('jobId', $options) ? $options['jobId'] : ''); $OUTPUT_FILE = (array_key_exists('outputFile', $options) ?                 $options['outputFile'] : '');  /*  * You can obtain an OAuth 2.0 client ID and client secret from the  * {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>  * For more information about using OAuth 2.0 to access Google APIs, please see:  * <https://developers.google.com/youtube/v3/guides/authentication>  * Please ensure that you have enabled the YouTube Data API for your project.  */ function getClient() {   $client = new Google_Client();   $client->setAuthConfigFile('client_secrets_php.json');   $client->addScope(       'https://www.googleapis.com/auth/yt-analytics-monetary.readonly');   $client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');   $client->setAccessType('offline');    // Load previously authorized credentials from a file.   $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);   if (file_exists($credentialsPath)) {     $accessToken = json_decode(file_get_contents($credentialsPath), true);   } else {     // Request authorization from the user.     $authUrl = $client->createAuthUrl();     printf('Open the following link in your browser:\n%s\n', $authUrl);     print 'Enter verification code: ';     $authCode = trim(fgets(STDIN));      // Exchange authorization code for an access token.     $accessToken = $client->authenticate($authCode);     $refreshToken = $client->getRefreshToken();      // Store the credentials to disk.     if(!file_exists(dirname($credentialsPath))) {       mkdir(dirname($credentialsPath), 0700, true);     }     file_put_contents($credentialsPath, json_encode($accessToken));     printf('Credentials saved to %s\n', $credentialsPath);      //fclose($fp);   }   $client->setAccessToken($accessToken);    // Refresh the token if it's expired.   if ($client->isAccessTokenExpired()) {     $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());     file_put_contents($credentialsPath, json_encode($client->getAccessToken()));   }    return $client; }  /**  * Expands the home directory alias '~' to the full path.  * @param string $path the path to expand.  * @return string the expanded path.  */ function expandHomeDirectory($path) {   $homeDirectory = getenv('HOME');   if (empty($homeDirectory)) {     $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');   }   return str_replace('~', realpath($homeDirectory), $path); }  /**  * Returns a list of reporting jobs. (jobs.listJobs)  *  * @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.  * @param string $onBehalfOfContentOwner A content owner ID.  */ function listReportingJobs(Google_Service_YouTubeReporting $youtubeReporting,     $onBehalfOfContentOwner = '', $includeSystemManaged = False) {   $reportingJobs = $youtubeReporting->jobs->listJobs(       array('onBehalfOfContentOwner' => $onBehalfOfContentOwner,             'includeSystemManaged' => $includeSystemManaged));   print ('REPORTING JOBS' . PHP_EOL . '**************' . PHP_EOL);   foreach ($reportingJobs as $job) {     print($job['reportTypeId'] . ':' . $job['id'] . PHP_EOL);   }   print(PHP_EOL); }  /**  * Lists reports created by a specific job. (reports.listJobsReports)  *  * @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.  * @param string $jobId The ID of the job.  * @param string $onBehalfOfContentOwner A content owner ID.  */ function listReportsForJob(Google_Service_YouTubeReporting $youtubeReporting,     $jobId, $onBehalfOfContentOwner = '') {   $reports = $youtubeReporting->jobs_reports->listJobsReports($jobId,       array('onBehalfOfContentOwner' => $onBehalfOfContentOwner));   print ('DOWNLOADABLE REPORTS' . PHP_EOL . '********************' . PHP_EOL);   foreach ($reports['reports'] as $report) {     print('Created: ' . date('d M Y', strtotime($report['createTime'])) .           ' (' . date('d M Y', strtotime($report['startTime'])) .           ' to ' . date('d M Y', strtotime($report['endTime'])) . ')' .           PHP_EOL .  '    ' . $report['downloadUrl'] . PHP_EOL . PHP_EOL);   } }  /**  * Download the report specified by the URL. (media.download)  *  * @param Google_Service_YouTubereporting $youtubeReporting YouTube Reporting service object.  * @param string $reportUrl The URL of the report to be downloaded.  * @param string $outputFile The file to write the report to locally.  * @param $htmlBody - html body.  */ function downloadReport(Google_Service_YouTubeReporting $youtubeReporting,     $reportUrl, $outputFile) {   $client = $youtubeReporting->getClient();   // Setting the defer flag to true tells the client to return a request that   // can be called with ->execute(); instead of making the API call immediately.   $client->setDefer(true);    // Call YouTube Reporting API's media.download method to download a report.   $request = $youtubeReporting->media->download('', array('alt' => 'media'));   $request = $request->withUri(new \GuzzleHttp\Psr7\Uri($reportUrl));   $responseBody = '';   try {     $response = $client->execute($request);     $responseBody = $response->getBody();   } catch (Google_Service_Exception $e) {     $responseBody = $e->getTrace()[0]['args'][0]->getResponseBody();   }   file_put_contents($outputFile, $responseBody);   $client->setDefer(false); }  // Define an object that will be used to make all API requests. $client = getClient(); // YouTube Reporting object used to make YouTube Reporting API requests. $youtubeReporting = new Google_Service_YouTubeReporting($client);  if ($CONTENT_OWNER_ID) {   if (!$DOWNLOAD_URL && !$JOB_ID) {     listReportingJobs($youtubeReporting, $CONTENT_OWNER_ID,                       $INCLUDE_SYSTEM_MANAGED);   } else if ($JOB_ID) {     listReportsForJob($youtubeReporting, $JOB_ID, $CONTENT_OWNER_ID);   } else if ($DOWNLOAD_URL && $OUTPUT_FILE) {     downloadReport($youtubeReporting, $DOWNLOAD_URL, $OUTPUT_FILE);   } }  ?> 

Python

次のサンプルでは、Python クライアント ライブラリを使用します。

例 1: レポートジョブを作成する

次のコードサンプルは、reportTypes.list メソッドを呼び出して、使用可能なレポートタイプのリストを取得します。次に、jobs.create メソッドを呼び出して新しいレポートジョブを作成します。

#!/usr/bin/python  # Create a reporting job for the authenticated user's channel or # for a content owner that the user's account is linked to. # Usage example: # python create_reporting_job.py --name='<name>' # python create_reporting_job.py --content-owner='<CONTENT OWNER ID>' # python create_reporting_job.py --content-owner='<CONTENT_OWNER_ID>' --report-type='<REPORT_TYPE_ID>' --name='<REPORT_NAME>'  import argparse import os  import google.oauth2.credentials import google_auth_oauthlib.flow from googleapiclient.discovery import build from googleapiclient.errors import HttpError from google_auth_oauthlib.flow import InstalledAppFlow   # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains  # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the {{ Google Cloud Console }} at # {{ https://cloud.google.com/console }}. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: #   https://developers.google.com/youtube/v3/guides/authentication # For more information about the client_secrets.json file format, see: #   https://developers.google.com/api-client-library/python/guide/aaa_client_secrets CLIENT_SECRETS_FILE = 'client_secret.json'  # This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for # authenticated user's account. Any request that retrieves earnings or ad performance metrics must # use this scope. SCOPES = ['https://www.googleapis.com/auth/yt-analytics-monetary.readonly'] API_SERVICE_NAME = 'youtubereporting' API_VERSION = 'v1'  # Authorize the request and store authorization credentials. def get_authenticated_service():   flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)   credentials = flow.run_console()   return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)  # Remove keyword arguments that are not set. def remove_empty_kwargs(**kwargs):   good_kwargs = {}   if kwargs is not None:     for key, value in kwargs.iteritems():       if value:         good_kwargs[key] = value   return good_kwargs  # Call the YouTube Reporting API's reportTypes.list method to retrieve report types. def list_report_types(youtube_reporting, **kwargs):   # Provide keyword arguments that have values as request parameters.   kwargs = remove_empty_kwargs(**kwargs)   results = youtube_reporting.reportTypes().list(**kwargs).execute()   reportTypes = results['reportTypes']    if 'reportTypes' in results and results['reportTypes']:     reportTypes = results['reportTypes']     for reportType in reportTypes:       print 'Report type id: %s\n name: %s\n' % (reportType['id'], reportType['name'])   else:     print 'No report types found'     return False    return True   # Call the YouTube Reporting API's jobs.create method to create a job. def create_reporting_job(youtube_reporting, report_type_id, **kwargs):   # Provide keyword arguments that have values as request parameters.   kwargs = remove_empty_kwargs(**kwargs)    reporting_job = youtube_reporting.jobs().create(     body=dict(       reportTypeId=args.report_type,       name=args.name     ),     **kwargs   ).execute()    print ('Reporting job "%s" created for reporting type "%s" at "%s"'          % (reporting_job['name'], reporting_job['reportTypeId'],              reporting_job['createTime']))   # Prompt the user to enter a report type id for the job. Then return the id. def get_report_type_id_from_user():   report_type_id = raw_input('Please enter the reportTypeId for the job: ')   print ('You chose "%s" as the report type Id for the job.' % report_type_id)   return report_type_id  # Prompt the user to set a job name def prompt_user_to_set_job_name():   job_name = raw_input('Please set a name for the job: ')   print ('Great! "%s" is a memorable name for this job.' % job_name)   return job_name   if __name__ == '__main__':   parser = argparse.ArgumentParser()   # The 'name' option specifies the name that will be used for the reporting job.   parser.add_argument('--content-owner', default='',       help='ID of content owner for which you are retrieving jobs and reports.')   parser.add_argument('--include-system-managed', default=False,       help='Whether the API response should include system-managed reports')   parser.add_argument('--name', default='',     help='Name for the reporting job. The script prompts you to set a name ' +          'for the job if you do not provide one using this argument.')   parser.add_argument('--report-type', default=None,     help='The type of report for which you are creating a job.')   args = parser.parse_args()    youtube_reporting = get_authenticated_service()    try:     # Prompt user to select report type if they didn't set one on command line.     if not args.report_type:       if list_report_types(youtube_reporting,                            onBehalfOfContentOwner=args.content_owner,                            includeSystemManaged=args.include_system_managed):         args.report_type = get_report_type_id_from_user()     # Prompt user to set job name if not set on command line.     if not args.name:       args.name = prompt_user_to_set_job_name()     # Create the job.     if args.report_type:       create_reporting_job(youtube_reporting,                            args,                            onBehalfOfContentOwner=args.content_owner)   except HttpError, e:     print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content) 

例 2: レポートを取得する

このコードサンプルでは、jobs.list メソッドを呼び出してレポート ジョブのリストを取得します。次に、jobId パラメータを特定のジョブ ID に設定して reports.list メソッドを呼び出し、そのジョブによって作成されたレポートを取得します。最後に、各レポートのダウンロード URL が印刷されます。

#!/usr/bin/python  ### # # This script retrieves YouTube Reporting API reports. Use cases: # 1. If you specify a report URL, the script downloads that report. # 2. Otherwise, if you specify a job ID, the script retrieves a list of #    available reports for that job and prompts you to select a report. #    Then it retrieves that report as in case 1. # 3. Otherwise, the list retrieves a list of jobs for the user or, #    if specified, the content owner that the user is acting on behalf of. #    Then it prompts the user to select a job, and then executes case 2 and #    then case 1. # Usage examples: # python retrieve_reports.py --content_owner_id=<CONTENT_OWNER_ID> --local_file=<LOCAL_FILE> # python retrieve_reports.py --content_owner_id=<CONTENT_OWNER_ID> --job_id=<JOB_ID> --local_file=<LOCAL_FILE> # python retrieve_reports.py --content_owner_id=<CONTENT_OWNER_ID> --report_url=<REPORT_URL> --local_file=<LOCAL_FILE> # ###  import argparse import os  import google.oauth2.credentials import google_auth_oauthlib.flow from googleapiclient.discovery import build from googleapiclient.errors import HttpError from googleapiclient.http import MediaIoBaseDownload from google_auth_oauthlib.flow import InstalledAppFlow from io import FileIO   # The CLIENT_SECRETS_FILE variable specifies the name of a file that contains # the OAuth 2.0 information for this application, including its client_id and # client_secret. You can acquire an OAuth 2.0 client ID and client secret from # the {{ Google Cloud Console }} at # {{ https://cloud.google.com/console }}. # Please ensure that you have enabled the YouTube Data API for your project. # For more information about using OAuth2 to access the YouTube Data API, see: #   https://developers.google.com/youtube/v3/guides/authentication # For more information about the client_secrets.json file format, see: #   https://developers.google.com/api-client-library/python/guide/aaa_client_secrets CLIENT_SECRETS_FILE = 'client_secret.json'  # This OAuth 2.0 access scope allows for read access to YouTube Analytics # monetary reports for the authenticated user's account. Any request that # retrieves earnings or ad performance metrics must use this scope. SCOPES = ['https://www.googleapis.com/auth/yt-analytics-monetary.readonly'] API_SERVICE_NAME = 'youtubereporting' API_VERSION = 'v1'  # Authorize the request and store authorization credentials. def get_authenticated_service():   flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)   credentials = flow.run_console()   return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)  # Remove keyword arguments that are not set. def remove_empty_kwargs(**kwargs):   good_kwargs = {}   if kwargs is not None:     for key, value in kwargs.iteritems():       if value:         good_kwargs[key] = value   return good_kwargs  # Call the YouTube Reporting API's jobs.list method to retrieve reporting jobs. def list_reporting_jobs(youtube_reporting, **kwargs):   # Only include the onBehalfOfContentOwner keyword argument if the user   # set a value for the --content_owner argument.   kwargs = remove_empty_kwargs(**kwargs)    # Retrieve the reporting jobs for the user (or content owner).   results = youtube_reporting.jobs().list(**kwargs).execute()    if 'jobs' in results and results['jobs']:     jobs = results['jobs']     for job in jobs:       print ('Reporting job id: %s\n name: %s\n for reporting type: %s\n'         % (job['id'], job['name'], job['reportTypeId']))   else:     print 'No jobs found'     return False    return True  # Call the YouTube Reporting API's reports.list method to retrieve reports created by a job. def retrieve_reports(youtube_reporting, **kwargs):   # Only include the onBehalfOfContentOwner keyword argument if the user   # set a value for the --content_owner argument.   kwargs = remove_empty_kwargs(**kwargs)    # Retrieve available reports for the selected job.   results = youtube_reporting.jobs().reports().list(     **kwargs   ).execute()    if 'reports' in results and results['reports']:     reports = results['reports']     for report in reports:       print ('Report dates: %s to %s\n       download URL: %s\n'         % (report['startTime'], report['endTime'], report['downloadUrl']))   # Call the YouTube Reporting API's media.download method to download the report. def download_report(youtube_reporting, report_url, local_file):   request = youtube_reporting.media().download(     resourceName=' '   )   request.uri = report_url   fh = FileIO(local_file, mode='wb')   # Stream/download the report in a single request.   downloader = MediaIoBaseDownload(fh, request, chunksize=-1)    done = False   while done is False:     status, done = downloader.next_chunk()     if status:       print 'Download %d%%.' % int(status.progress() * 100)   print 'Download Complete!'   # Prompt the user to select a job and return the specified ID. def get_job_id_from_user():   job_id = raw_input('Please enter the job id for the report retrieval: ')   print ('You chose "%s" as the job Id for the report retrieval.' % job_id)   return job_id  # Prompt the user to select a report URL and return the specified URL. def get_report_url_from_user():   report_url = raw_input('Please enter the report URL to download: ')   print ('You chose "%s" to download.' % report_url)   return report_url  if __name__ == '__main__':   parser = argparse.ArgumentParser()   parser.add_argument('--content_owner', default='',       help='ID of content owner for which you are retrieving jobs and reports')   parser.add_argument('--job_id', default=None,       help='ID of the job for which you are retrieving reports. If not ' +            'provided AND report_url is also not provided, then the script ' +            'calls jobs.list() to retrieve a list of jobs.')   parser.add_argument('--report_url', default=None,       help='URL of the report to retrieve. If not specified, the script ' +            'calls reports.list() to retrieve a list of reports for the ' +            'selected job.')   parser.add_argument('--local_file', default='yt_report.txt',       help='The name of the local file where the downloaded report will be written.')   args = parser.parse_args()    youtube_reporting = get_authenticated_service()   try:     # If the user has not specified a job ID or report URL, retrieve a list     # of available jobs and prompt the user to select one.     if not args.job_id and not args.report_url:       if list_reporting_jobs(youtube_reporting,                              onBehalfOfContentOwner=args.content_owner):         args.job_id = get_job_id_from_user()      # If the user has not specified a report URL, retrieve a list of reports     # available for the specified job and prompt the user to select one.     if args.job_id and not args.report_url:       retrieve_reports(youtube_reporting,                        jobId=args.job_id,                        onBehalfOfContentOwner=args.content_owner)       args.report_url = get_report_url_from_user()      # Download the selected report.     if args.report_url:       download_report(youtube_reporting, args.report_url, args.local_file)   except HttpError, e:     print 'An HTTP error %d occurred:\n%s' % (e.resp.status, e.content)