""" API Client Connector ================== Handles client setup and auth for the YouTube API. Yanked from ows-label-audit. """ from googleapiclient.discovery import build import httplib2 from oauth2client.client import SignedJwtAssertionCredentials import os import time class ServiceMapping: """ Google API Service Mapping ================== Thin wrapper around the Google client library. Lazily handles oauth setup and builds the service client for the partner API. """ PARTNER_API_VERSION = 'v1' PARTNER_API_NAME = 'youtubePartner' DATA_API_VERSION = 'v3' DATA_API_NAME = 'youtube' def __init__(self, service_email, key_file): self.service_email = service_email self.key_file = key_file self._client = None self._youtube_partner = None self._youtube_data = None def authorize(self): """Create and authorize a Google API client. To be called when the client has not been initialized or its access token has expired. """ credentials = SignedJwtAssertionCredentials( self.service_email, self.key_file.contents, scope=['https://www.googleapis.com/auth/youtubepartner']) self._client = credentials.authorize(httplib2.Http()) @property def client(self): """Create and authorize a Google API client. Return: httplib2.Http: httlib2 client object """ if not self._client: self.authorize() return self._client @property def youtube_partner(self): """Lazily initialize the YouTube API discovery resource for the partner API. Return: googleapiclient.discovery.Resource: partner API resource """ if not self._youtube_partner: self._youtube_partner = build( self.PARTNER_API_NAME, self.PARTNER_API_VERSION, http=self.client) return self._youtube_partner @property def youtube_data(self): if not self._youtube_data: credentials = SignedJwtAssertionCredentials( self.service_email, self.key_file.contents, scope=['https://www.googleapis.com/auth/youtube']) client = credentials.authorize(httplib2.Http()) self._youtube_data = build( self.DATA_API_NAME, self.DATA_API_VERSION, http=client) return self._youtube_data class KeyFile: """ Google API key file reader ================== Lazily reads the contents of the given key file from the keys directory. """ def __init__(self, file_name): self.file_name = file_name self._contents = None @property def contents(self): """Reads the contents of the P12 key file specified in the config. Return: bytes: contents of the key file """ if self._contents: return self._contents if not self.file_name: raise Exception('Missing Google API key file name') full_key_path = os.path.join( os.path.realpath(os.path.dirname(__file__)), 'keys', self.file_name) if not os.access(full_key_path, os.R_OK): raise Exception('Cannot read Google API key file ' + full_key_path) key_file = open(full_key_path, 'rb') self._contents = key_file.read() key_file.close() return self._contents def paginate(api_call, sleep_time): def paginated_call(**kwargs): keep_going = True page_token = None api_params = kwargs while keep_going: api_params['pageToken'] = page_token results = api_call(**api_params).execute() if results: yield results page_token = results.get('nextPageToken') if page_token: time.sleep(sleep_time) else: keep_going = False return paginated_call