YouTube Reporting API - Data Model

중요: 예정된 정책 변경사항은 YouTube Reporting API 보고서를 검색할 수 있는 기간에 영향을 미칩니다. 변경 후에는 일일 API 보고서 및 백업 광고 보고서가 생성된 시점부터 180일이 아닌 60일 동안 사용할 수 있습니다. 이전 데이터 보고서는 생성된 후 30일 동안 제공됩니다.

이 변경사항은 현재 2018년 7월부터 적용될 예정이며, 새로운 정책은 모든 보고서 및 보고 작업에 적용됩니다. 이 변경사항에 관한 자세한 내용은 API의 업데이트 기록을 참고하세요.

YouTube Reporting API는 채널 또는 콘텐츠 소유자의 YouTube 분석 데이터 세트가 포함된 사전 정의된 보고서를 지원합니다. 이 보고서를 통해 YouTube Analytics API 또는 크리에이터 스튜디오의 분석 섹션에서 쿼리할 수 있는 대량 데이터 세트를 다운로드할 수 있습니다.

개요

이러한 보고서의 보고서 측정기준은 측정기준 또는 측정항목 중 하나로 분류됩니다.

  • 측정기준은 액션 발생일 또는 사용자 거주 국가와 같이 데이터를 집계하는 데 사용되는 공통 기준입니다. 보고서에서는 데이터의 각 행에 측정기준 값의 고유한 조합이 있습니다.
  • 측정항목은 사용자 활동, 광고 실적 또는 예상 수익과 관련된 개별 측정값입니다. 사용자 활동 측정항목에는 동영상 조회수 및 평점 (좋아요 및 싫어요) 등이 포함됩니다.

예를 들어 채널의 기본 사용자 활동 보고서에는 다음과 같은 측정기준이 포함되어 있습니다.

  • 날짜: 활동이 발생한 날짜입니다.
  • channel_id: 활동과 연결된 YouTube 채널입니다.
  • video_id: 활동과 연결된 YouTube 동영상입니다.
  • live_or_on_demand: 시청자가 실시간 동영상 스트림을 시청했는지를 나타내는 값
  • subscribed_status: 시청자가 채널을 구독했는지를 나타내는 값입니다.
  • country_code: 시청자가 위치한 국가입니다.

보고서에는 조회수, 좋아요, average_view_duration_seconds와 같은 다양한 측정항목도 포함됩니다. 보고서를 검색하고 가져온 후에 일반적인 측정기준 값을 기준으로 여러 가지 계산을 할 수 있습니다.

YouTube 분석 보고서 검색

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_a1입니다.

지원되는 채널 보고서콘텐츠 소유자 보고서를 정의하는 문서에서 보고서 이름을 확인할 수도 있습니다.

3단계: 보고 작업 만들기

YouTube는 보고서에 대한 보고 작업을 만들기 전에는 보고서를 생성하지 않습니다. 따라서 보고서는 실제로 검색하려는 채널 및 콘텐츠 소유자만 생성됩니다.

보고 작업을 만들려면 API의 jobs.create 메서드를 호출합니다. 요청 본문에 다음 값을 설정합니다.

  • reportTypeId 속성의 값을 2단계에서 검색한 보고서 ID로 설정합니다.
  • name 속성의 값을 보고서에 연결할 이름으로 설정합니다.

jobs.create 메서드에 대한 API 응답에는 작업을 고유하게 식별하는 ID를 지정하는 Job 리소스가 포함됩니다. 작업이 생성된 후 48시간 이내에 보고서를 검색할 수 있으며, 사용 가능한 첫 번째 보고서는 작업을 예약한 날에 대한 것입니다.

예를 들어 작업을 2015년 9월 1일에 예약하면 2015년 9월 1일에 대한 보고서는 2015년 9월 3일에 생성됩니다. 2015년 9월 2일에 대한 보고서는 2015년 9월 4일에 게시됩니다.

4단계: 작업 ID 검색

참고: 애플리케이션이 3단계에서 반환된 작업 ID를 저장한 경우 이 단계를 건너뛸 수 있습니다.

jobs.list 메서드를 호출하여 예약된 작업 목록을 검색합니다. 반환된 각 Job 리소스의 reportTypeId 속성은 작업에서 생성되는 보고서의 유형을 식별합니다. 다음 단계에서 애플리케이션에 동일한 리소스의 id 속성 값이 필요합니다.

5단계: 보고서의 다운로드 URL 가져오기

jobs.reports.list 메서드를 호출하여 작업에 대해 생성된 보고서 목록을 검색합니다. 요청에서 jobId 매개변수를 검색하려는 보고서의 작업 ID로 설정합니다.

팁: createdAfter 매개변수를 사용하여 API가 지정된 시간 이후에 생성된 보고서만 반환해야 함을 나타냅니다. 이 매개변수를 사용하여 API가 아직 처리하지 않은 보고서만 반환하도록 할 수 있습니다.

API 응답에는 작업의 Report 리소스 목록이 포함됩니다. 각 리소스는 고유한 24시간 동안의 데이터가 포함된 보고서를 참조합니다. YouTube는 데이터를 사용할 수 없는 날에 대해 다운로드 가능한 보고서를 생성합니다. 이러한 보고서에는 헤더 행이 포함되지만 추가 데이터는 포함되지 않습니다.

  • 리소스의 startTimeendTime 속성은 보고서 데이터에서 다루는 기간을 식별합니다.
  • 리소스의 downloadUrl 속성은 보고서를 가져올 수 있는 URL을 식별합니다.

  • 리소스의 createTime 속성은 보고서가 생성된 날짜와 시간을 지정합니다. 애플리케이션은 이 값을 저장하고 이를 사용하여 이전에 다운로드한 보고서가 변경되었는지 확인해야 합니다.

6단계: 보고서 다운로드

5단계에서 얻은 downloadUrl에 HTTP GET 요청을 보내 보고서를 가져옵니다.

다운로드 요청에 gzip 압축을 사용 설정하면 보고서를 다운로드하는 데 필요한 대역폭을 줄일 수 있습니다. 애플리케이션에서 API 응답의 압축을 풀기 위해 추가 CPU 시간이 필요하지만 일반적으로 보다 적은 네트워크 리소스를 사용함으로써 얻는 장점이 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를 사용하여 다운로드하고 가져와야 하는 보고서를 식별합니다. 그러나 두 개의 새 보고서에 동일한 startTimeendTime 속성 값이 있는 경우에는 최신 createTime 값으로 된 보고서만 가져오세요.

  • 보고서에는 YouTube 리소스와 연결된 ID가 포함되며 YouTube Data API를 사용하여 리소스에 대한 추가 메타데이터를 검색할 수 있습니다. YouTube API 서비스 개발자 정책 (III.E.4.b~III.E.4.d 섹션)에 명시된 대로 API 클라이언트는 30일 후 API에서 저장된 리소스 메타데이터를 삭제하거나 새로고침해야 합니다.

보고서 특성

API 보고서는 버전이 지정된 .csv(쉼표로 구분된 값) 파일이며 다음과 같은 특성을 가집니다.

  • 각 보고서에는 태평양 표준시 기준 오전 12시부터 오후 11시 59분까지 고유한 24시간 동안의 데이터가 포함되어 있습니다. 따라서 모든 보고서에서는 날짜 측정기준 값이 항상 동일합니다.

  • 보고서는 매일 업데이트됩니다.

  • YouTube는 데이터를 사용할 수 없는 날에 대해 다운로드 가능한 보고서를 생성합니다. 이러한 보고서에는 헤더 행이 포함되지만 추가 데이터는 포함되지 않습니다.

  • 중요: 예정된 정책 변경사항은 YouTube Reporting API 보고서를 검색할 수 있는 기간에 영향을 미칩니다. 이 변경사항은 2018년 7월부터 적용될 예정이며 전 세계 모든 보고서 및 보고 작업에 적용됩니다.

    • 변경 전에는 API 보고서가 생성된 후 최대 180일 동안 사용할 수 있습니다.
    • 변경 후에는 새 보고서 작업에 대해 생성된 이전 데이터를 제외하고 API 보고서가 생성된 후 60일 동안 사용할 수 있습니다. 이미 60일이 지난 보고서는 정책 변경이 시행되면 더 이상 액세스할 수 없습니다.
    • 변경 후 이전 데이터가 포함된 보고서는 생성된 후 30일 동안 사용할 수 있습니다. 과거 데이터가 포함되어 있으며 이미 생성된 지 30일이 지난 보고서는 정책 변경사항이 적용되면 더 이상 액세스할 수 없습니다.
  • 보고서 데이터는 필터링되지 않습니다. 따라서 채널 보고서에는 삭제된 리소스와 관련된 다음 단락에 명시된 경우를 제외하고 채널의 동영상 또는 재생목록에 대한 모든 데이터가 포함됩니다. 마찬가지로 콘텐츠 소유자 보고서에는 콘텐츠 소유자 채널에 대한 모든 데이터 (동영상, 재생목록, 광고 실적 등)가 포함됩니다. 단, 다음은 예외입니다.

    보고서 데이터는 필터링되지 않지만 2018년 6월 1일 이후의 기간에 대한 데이터가 포함된 보고서에는 보고서가 생성된 날짜 최소 30일 전에 삭제된 YouTube 리소스에 대한 참조가 포함되지 않습니다.

  • 보고서 데이터가 정렬되지 않았습니다.

  • 보고서에서는 측정항목이 없는 행을 생략합니다. 즉, 측정항목이 없는 행은 보고서에서 제외됩니다. 예를 들어 알바니아에서 동영상 조회수가 없는 날의 보고서에는 해당 날짜의 알바니아 행이 포함되지 않습니다.

  • 보고서에는 채널에 대한 모든 동영상의 총 조회수 등 측정항목에 대한 요약 데이터를 제공하는 행이 포함되지 않습니다. 이 값의 총합을 보고서의 값 합계로 계산할 수 있지만, 이 합계에는 위에서 언급한 삭제된 동영상에 대한 측정항목이 포함되지 않을 수 있습니다. YouTube Analytics API를 사용하여 총계를 검색할 수도 있습니다. YouTube Analytics API는 삭제된 리소스가 API 응답에서 명시적으로 참조되지 않더라도 해당 리소스의 측정항목을 포함하는 총 값을 반환합니다.

백업 광고 데이터

백업 광고 데이터는 이전에 제공된 세트를 대체하는 데이터 세트를 의미합니다. 백필 데이터 보고서가 있으면 애플리케이션은 새 보고서를 검색하고 수정된 데이터 세트와 일치하도록 저장된 데이터를 업데이트해야 합니다. 예를 들어 애플리케이션에서 보고서에 포함된 기간의 이전 데이터를 삭제한 다음 새 데이터 세트를 가져올 수 있습니다.

YouTube에 백업 광고 데이터가 있으면 새 보고서 ID를 사용하여 새 보고서가 생성됩니다. 이 경우 보고서의 startTimeendTime 속성 값은 이전에 사용 가능했던 이전에 시작한 보고서의 시작 및 종료 시간과 일치합니다.

2018년 6월 1일 이후의 기간에 대한 데이터가 포함된 백업 광고 보고서에는 보고서 생성일로부터 최소 30일 전에 삭제된 YouTube 리소스에 대한 참조가 포함되지 않습니다.

이전 데이터

새로운 보고 작업을 예약하면 YouTube에서는 사용자가 작업을 만들기 전의 기간을 포함한 이전 보고서를 생성합니다. 따라서 이 문서에서 이전 데이터는 보고 작업이 예약되기 이전의 기간에 대한 데이터가 포함된 보고서를 나타냅니다.

중요: 예정된 정책 변경사항은 이전 보고서 데이터가 생성되는 기간에 영향을 미칩니다. 이 변경사항은 2018년 7월부터 적용될 예정이며 전 세계 모든 보고서 및 보고 작업에 적용됩니다.

  • 정책 변경 전에 새로운 보고 작업을 예약할 때, YouTube는 작업을 생성하기 전 180일 동안의 보고서를 생성합니다.
  • 정책이 변경된 후 새 보고 작업을 예약하면 YouTube는 그날부터 해당 작업을 만들기 전 30일 동안의 보고서를 생성합니다.

이전 보고서가 제공되면 바로 게시됩니다. 일반적으로 모든 과거 데이터는 며칠 내로 작업에 대해 게시됩니다. 보고서 특성 섹션에 설명된 대로 2018년 7월에 정책 변경사항이 적용될 예정입니다. 이전 데이터가 포함된 보고서는 생성된 후 30일 동안 사용할 수 있습니다. 이전 데이터 외의 데이터가 포함된 보고서는 정책 변경 후 60일 동안 사용할 수 있습니다.

데이터 익명처리

YouTube 시청자의 익명성을 보장하기 위해 일부 측정기준의 값은 같은 행의 측정항목이 특정 기준을 충족하는 경우에만 반환됩니다.

예를 들어 채널의 동영상 트래픽 소스 보고서에서 각 행에는 traffic_source_typetraffic_source_detail을 비롯한 여러 측정기준이 포함됩니다. 각 행에는 조회수를 비롯한 다양한 측정항목도 포함됩니다. YouTube 검색에서 발생한 트래픽을 설명하는 행에서 traffic_source_detail 측정기준은 트래픽을 유도한 검색어를 나타냅니다.

이 예시에서는 다음 규칙이 적용됩니다.

  • 트래픽 소스 보고서는 특정 날짜에 특정 동영상의 조회수가 일정 수 이상으로 이어진 경우에만 검색어(traffic_source_detail)를 식별합니다. 이 경우 조회수는 측정항목, video_id는 집계 측정기준, traffic_source_detail은 익명처리된 측정기준입니다.

  • 보고서에는 조회수 기준을 충족하지 않는 모든 traffic_source_detail 값의 측정항목을 집계하는 추가 행이 포함되어 있습니다. 이 행은 해당 검색어와 관련된 총 조회수를 보고하지만, 검색어 자체는 식별하지 않습니다.

다음 표는 이러한 규칙을 보여줍니다. 첫 번째 표에는 YouTube에서 트래픽 소스 보고서를 생성하는 데 사용할 원시 데이터 세트가 나와 있고 두 번째 표에는 보고서 자체가 포함되어 있습니다. 이 예에서 조회수 임계값은 10이며, 이는 보고서에서 특정 날짜에 특정 동영상의 조회수가 10회 이상인 경우에만 검색어를 식별합니다. (실제 기준점은 변경될 수 있습니다.)

동영상의 원시 YouTube 검색 트래픽 데이터

아래 데이터는 특정 날짜의 특정 동영상에 대한 YouTube 검색 트래픽을 설명한다고 가정하겠습니다.

검색어 조회수 예상 시청 시간(분)
강남 스타일 100 200
싸이 15 25
강남 9 15
강남 5 8
승마 댄스 2 5

샘플 트래픽 소스 보고서

다음 표는 트래픽 소스 보고서에서 YouTube가 이전 섹션의 원시 데이터에 대해 발췌한 내용을 보여줍니다. 실제 보고서에는 더 많은 측정기준 및 측정항목이 포함됩니다. 이 예에서 보고서를 통해 조회수가 10회 이상인 경우에만 검색어를 확인할 수 있습니다. 실제 기준은 변경될 수 있습니다.

보고서의 세 번째 행에서 trafficSourceDetail 측정기준 값은 NULL입니다. viewsestimatedMinutesWatched 측정항목에는 조회수 10회 미만의 조회수를 기록한 3가지 검색어의 총 조회수와 시청 시간(분)이 포함되어 있습니다.

트래픽 소스 세부정보 조회수 예상 시청 시간(분)
강남 스타일 100 200
싸이 15 25
NULL 16 28

익명처리가 가능한 측정기준

다음 표에서는 연결된 측정항목 값이 특정 기준을 충족하지 않는 경우 익명처리된 측정기준 값을 식별합니다. 각각의 경우에 측정항목의 값은 다른 측정기준에서 집계됩니다. 예를 들어 측정항목이 조회수이고 집계 측정기준이 video_id인 경우 동영상 동영상을 특정 횟수만큼 시청하지 않은 경우 측정기준 값이 익명처리됩니다.

측정항목 집계 측정기준 익명처리된 측정기준 익명처리된 값
구독자 수 증가 channel_id 국가_코드 ZZ
구독자 수 증가 channel_id state_code US-ZZ
구독자_손실 channel_id 국가_코드 ZZ
구독자_손실 channel_id state_code US-ZZ
댓글 동영상 ID 국가_코드 ZZ
댓글 동영상 ID state_code US-ZZ
좋아요 동영상 ID 국가_코드 ZZ
좋아요 동영상 ID state_code US-ZZ
싫어요 동영상 ID 국가_코드 ZZ
싫어요 동영상 ID state_code US-ZZ
조회수 동영상 ID 연령대 NULL
조회수 동영상 ID 성별 NULL
조회수 video_idtraffic_source_detail traffic_source_detail NULL
채널 구독자 수 channel_id subscribe__status NULL

코드 샘플

다음 코드 샘플은 API를 사용하여 보고 작업을 만든 다음 해당 작업의 보고서를 검색하는 방법을 보여줍니다. 언어별로 두 가지 코드 샘플이 제공됩니다.

  1. 첫 번째 코드 샘플은 사용 가능한 보고서 유형 목록을 검색한 후 새 보고 작업을 만드는 방법을 보여줍니다.

  2. 두 번째 코드 샘플은 특정 작업에 대한 보고서를 검색하는 방법을 보여줍니다. 작업이 생성된 후 48시간 이내에 보고서를 검색할 수 있습니다.

참고: 다음 코드 샘플은 지원되는 일부 프로그래밍 언어를 나타내지 않을 수 있습니다. 지원되는 언어 목록은 클라이언트 라이브러리 문서를 참고하세요.

자바

다음 샘플은 자바 클라이언트 라이브러리를 사용합니다.

예 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 메서드를 호출하여 보고 작업 목록을 검색합니다. 그런 다음 특정 작업 ID로 설정된 jobId 매개변수를 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 메서드를 호출하여 보고 작업 목록을 검색합니다. 그런 다음 특정 작업 ID로 설정된 jobId 매개변수를 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 메서드를 호출하여 보고 작업 목록을 검색합니다. 그런 다음 특정 작업 ID로 설정된 jobId 매개변수를 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)