"""Api Base. Contains the raw methods to make Api Requests. """ import requests from podcast import config from podcast.connectors import sentry from podcast.constants import api as api_constants from podcast.constants import error from podcast.models import network from podcast.utils import exc class ApiBase: """API base methods.""" def __init__(self, podcast_network_id='', is_org=False): """Initialize megaphone api. Args: podcast_network_id (int): Network id in podcast application """ if is_org: self.megaphone_url = api_constants.MEGAPHONE_ORG_API_BASE_URL else: self.megaphone_url = network.get_megaphone_url(podcast_network_id) def _get(self, url): """Get request to megaphone api. Args: url (string): The api base url Returns: dict: containing the result from megaphone api. """ api_url = '{0}/{1}'.format(self.megaphone_url, url) response = requests.get(api_url, headers=self._headers()) self._error_check(response) return response.json() def _paginated_get(self, url): """Get paginated request to megaphone api. Args: url (string): The api base url Returns: dict: containing the paginated result from megaphone api. """ api_url = '{0}/{1}'.format(self.megaphone_url, url) response = requests.get(api_url, headers=self._headers()) self._error_check(response) return { 'items': response.json(), 'pagination': { 'total_records': int(response.headers['X-Total']) } } def _paginated_get_all(self, url): """Get paginated request to megaphone api. Args: url (string): The api base url Returns: dict: containing the paginated result from megaphone api. """ per_page = 500 total = per_page + 1 page = 1 all_pages = [] while total > per_page * (page - 1): response = self._paginated_get('{}?page={}&per_page={}'.format(url, page, per_page)) total = response['pagination']['total_records'] all_pages += response['items'] page += 1 return all_pages def _post(self, url, data): """Post request to megaphone api. Args: url (string): The api base url Returns: dict: containing the result from megaphone api. """ api_url = '{0}/{1}'.format(self.megaphone_url, url) response = requests.post( api_url, headers=self._headers(), json=data) self._error_check(response) return response.json() def _put(self, url, data, is_audio_processing=False): """Put request to megaphone api. Args: url (string): The api base url is_audio_processing (bool): Flag that indicates if megaphone still processing the audio file. data (dict): Data to be updated in megaphone. Returns: dict: containing the result from megaphone api. """ api_url = '{0}/{1}'.format(self.megaphone_url, url) response = requests.put( api_url, headers=self._headers(), json=data) self._error_check(response, is_audio_processing) return response.json() def _delete(self, url): """Delete request to megaphone api. Args: url (string): The api base url Returns: dict: containing the result from megaphone api. """ api_url = '{0}/{1}'.format(self.megaphone_url, url) response = requests.delete(api_url, headers=self._headers()) self._error_check(response) return response.json() def _error_check(self, response, is_audio_processing=False): """Check request for error responses. Args: response (dict): The api base url is_audio_processing (bool): Flag is useful in put request and defaults to False for other requests. It is helpful to provide better error info if megaphone still processing the audio file. Returns: dict: containing the result from megaphone api. """ if response.status_code < 400: return message = response.text if response.status_code in [400, 403]: message = {**response.json(), 'is_audio_processing': is_audio_processing} if response.status_code in [500, 501, 502, 503, 504]: message = {'error': message, 'is_megaphone_server_error': True} if sentry.sentry_client: header = 'Token token={0}'.format(config.MEGAPHONE_API_TOKEN) sentry.send_to_sentry(message, header, response.status_code, error.ERROR_MESSAGE_MEGAPHONE_API) raise exc.MegaphoneError(message, response.status_code) def _headers(self): """Get headers to request megaphone api. Returns: dict: A dictionary that contains the authorization and content type headers. """ return { 'Authorization': 'Token token={0}'.format( config.MEGAPHONE_API_TOKEN) }