YouTube Reporting API - Data Model

중요: 일일 API 보고서 및 백필 보고서는 생성된 후 60일 동안 사용할 수 있습니다. 이전 데이터 보고서는 생성된 후 30일 동안 사용할 수 있습니다.

이 정책은 전역적으로 모든 보고서 및 보고 작업에 적용됩니다. 자세한 내용은 YouTube Reporting API의 업데이트 기록을 참고하세요.

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

또한 API는 보고서 메뉴에서 해당 보고서에 액세스할 수 있는 콘텐츠 소유자가 사용할 수 있는, 자동으로 생성되는 시스템 관리 보고서 집합을 지원합니다. 이 보고서에는 광고 수익 데이터와 YouTube Premium 구독 수익 데이터가 포함됩니다. 자세한 내용은 시스템 관리 보고서 문서를 참조하세요.

개요

이러한 보고서의 보고서 필드는 측정기준 또는 측정항목으로 지정됩니다.

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

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

  • : 활동이 발생한 날짜입니다.
  • 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_a1입니다.

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

3단계: 보고 작업 만들기

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

보고 작업을 만들려면 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로 설정합니다.

도움말: API가 지정된 시간 이후에 생성된 보고서만 반환해야 함을 나타내려면 createdAfter 매개변수를 사용하세요. 이 매개변수를 사용하면 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 매개변수를 생략합니다.

      보고서를 검색하여 성공적으로 처리할 때마다 최신 보고서가 생성된 날짜 및 시간에 해당하는 타임스탬프를 저장합니다. 그런 다음 API를 호출할 때마다 백필된 데이터가 있는 새 보고서를 포함하여 새 보고서만 가져오도록 reports.list 메서드를 연속적으로 호출할 때마다 createdAfter 매개변수 값을 업데이트합니다.

      보호 수단으로 보고서를 검색하기 전에 보고서의 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는 데이터가 없는 날에 대해서는 다운로드 가능한 보고서를 생성합니다. 이러한 보고서에는 헤더 행이 포함되지만 추가 데이터는 포함되지 않습니다.

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

    보고서 데이터는 필터링되지 않지만 보고서 생성 최소 30일 전에 삭제된 YouTube 리소스에 대한 참조는 보고서에 포함되지 않습니다.

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

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

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

데이터 백필

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

YouTube에 백업 광고 데이터가 있으면 새 보고서 ID로 새 보고서를 생성합니다. 이 경우 보고서의 startTimeendTime 속성 값은 이전에 사용할 수 있었고 이전에 다운로드했을 수 있는 보고서의 시작 및 종료 시간과 일치합니다.

백필 보고서에는 보고서가 생성된 날짜로부터 최소 30일 전에 삭제된 YouTube 리소스에 대한 참조가 포함되지 않습니다.

이전 데이터

새 보고 작업을 예약하면 YouTube는 해당 날짜 이후의 이전 보고서를 생성하고 사용자가 작업을 만든 시간 전 30일 동안의 보고서를 생성합니다. 따라서 이 문서에서 이전 데이터는 보고 작업이 예약되기 전의 일정 기간 동안의 데이터가 포함된 보고서를 의미합니다.

이력 보고서는 제공되는 즉시 게시됩니다. 일반적으로 모든 이전 데이터는 며칠 내에 작업에 대해 게시됩니다. 보고서 특성 섹션에 설명된 대로 이전 데이터가 포함된 보고서는 생성된 후 30일 동안 사용할 수 있습니다. 이전 데이터 이외의 데이터가 포함된 보고서는 60일 동안 사용할 수 있습니다.

데이터 익명처리

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

예를 들어 채널의 동영상 트래픽 소스 보고서에서는 각 행에 trafficSourceType, trafficSourceDetail 등 여러 측정기준이 포함됩니다. 또한 각 행에는 조회수를 비롯한 다양한 측정항목이 포함되어 있습니다. YouTube 검색에서 발생한 트래픽을 설명하는 행에서 trafficSourceDetail 측정기준은 트래픽으로 이어진 검색어를 식별합니다.

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

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

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

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

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

아래 데이터가 특정 날짜에 특정 동영상으로 발생한 YouTube 검색 트래픽을 나타낸다고 가정해 보겠습니다.

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

샘플 트래픽 소스 보고서

다음 표는 YouTube가 이전 섹션의 원시 데이터에 대해 생성하는 트래픽 소스 보고서의 일부입니다. 실제 보고서에는 더 많은 측정기준 및 측정항목이 포함됩니다. 이 예에서는 보고서에 10회 이상의 조회가 발생한 경우에만 검색어가 식별됩니다. 실제 기준은 변경될 수 있습니다.

보고서의 세 번째 행에서 trafficSourceDetail 측정기준 값은 NULL입니다. viewsestimatedMinutesWatched 측정항목에는 조회수가 10회 미만인 검색어 3개의 통합 조회수 및 시청 시간(분)이 포함됩니다.

trafficSourceDetail 조회수 estimatedMinutesWatched
강남 스타일 100 200
싸이 15 25
NULL 16 28

익명처리가 적용되는 측정기준

다음 표에는 관련 측정항목 값이 특정 기준을 충족하지 않는 경우 익명처리되는 측정기준 값이 나와 있습니다. 각각의 경우 측정항목의 값이 다른 측정기준과 함께 집계됩니다. 예를 들어 측정항목이 조회수이고 집계 측정기준이 동영상인 경우 동영상이 특정 횟수만큼 조회되지 않는 한 측정기준 값은 익명처리됩니다.

측정항목 측정기준 집계 익명처리된 측정기준 익명처리된 값
subscribersGained channel country ZZ
subscribersGained channel province US-ZZ
subscribersLost channel country ZZ
subscribersLost channel province US-ZZ
댓글 동영상 country ZZ
댓글 동영상 province US-ZZ
좋아요 동영상 country ZZ
좋아요 동영상 province US-ZZ
싫어요 동영상 country ZZ
싫어요 동영상 province US-ZZ
조회수 동영상 ageGroup NULL
조회수 동영상 gender[성별] NULL
조회수 videotrafficSourceDetail trafficSourceDetail NULL
채널 구독자 수 channel subscribedStatus NULL

코드 샘플

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

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

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

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

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;
    }}

2,399필리핀

다음 샘플은 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)