Source code for matchlight.connection

"""Manages a Matchlight API connection."""
from __future__ import absolute_import

import os

import requests
import requests.adapters
import requests.exceptions
import requests.packages.urllib3 as requests_urllib3

import matchlight.error


__all__ = (
    'Connection',
    'MATCHLIGHT_API_URL_V2',
)


MATCHLIGHT_API_URL_V2 = 'https://api.matchlig.ht/api/v2'


[docs]class Connection(object): """Matchlight API connection object.""" def __init__(self, access_key=None, secret_key=None, https_proxy=None, insecure=False, endpoint=None, search_endpoint=None): """Initializes a new API connection. Args: access_key (str, optitonal): The user's Matchlight Public API access key. If not passed as an argument this value must be set using the ``MATCHLIGHT_ACCESS_KEY`` environment variable. secret_key (str, optional): The user's Matchlight Public API access key. If not passed as an argument this value must be set using the ``MATCHLIGHT_SECRET_KEY`` environment variable. https_proxy (str): A string defining the HTTPS proxy to use. Defaults to None. insecure (bool, optional): Whether or not to verify certificates for the HTTPS proxy. Defaults to ``False`` (certificates will be verified). endpoint (str, optional): Base URL for requests. Defaults to ``'https://api.matchlig.ht/api/v2'``. search_endpoint (str, optional): Base URL for all search API requests. """ if access_key is None: access_key = os.environ.get('MATCHLIGHT_ACCESS_KEY', None) if secret_key is None: secret_key = os.environ.get('MATCHLIGHT_SECRET_KEY', None) if access_key is None or secret_key is None: raise matchlight.error.SDKError( 'The APIConnection object requires your Matchlight ' 'API access_key and secret_key either be passed as input ' 'parameters or set in the MATCHLIGHT_ACCESS_KEY and ' 'MATCHLIGHT_SECRET_KEY environment variables.') if endpoint is None: endpoint = MATCHLIGHT_API_URL_V2 if search_endpoint is None: search_endpoint = MATCHLIGHT_API_URL_V2 self.access_key = access_key self.secret_key = secret_key self.proxy = {'https': https_proxy} self.insecure = insecure self.endpoint = endpoint self.search_endpoint = search_endpoint self.session = requests.Session() self.session.mount( self.endpoint, requests.adapters.HTTPAdapter( max_retries=requests_urllib3.util.Retry( total=5, status_forcelist=[500, 502, 503, 504])), )
[docs] def request(self, path, data=None, endpoint=None, **kwargs): """Send an HTTP request to the Matchlight API. Args: path (str): The path of request URL without the URL base. e.g. ``/search``. data (dict or list): Serializable data for ``POST`` requests. Defaults to ``None``. endpoint (str, optional): option to pass a different endpoint for each request. Defaults to Connection().endpoint Returns: A :class:`requests.models.Response` object. Raises: ConnectionError: Raised when there is an ``RetryError`` or ``ConnectionError`` from ``requests``. APIError: Raised when API does not return a 200, including error and custom message, if available. """ # Allows SDK to use different endponts for search if endpoint is None: endpoint = self.endpoint url = ''.join([endpoint, path]) method = 'GET' if data is None else 'POST' if 'timeout' not in kwargs: # API timeout is 90s kwargs['timeout'] = 91.0 response = self._request( method, url, data=data, headers={ 'Content-Type': 'application/json', 'Matchlight-Request-Source': 'python-sdk', 'Matchlight-Request-Source-Version': matchlight.__version__, }, auth=(self.access_key, self.secret_key), proxies=self.proxy, verify=not self.insecure, **kwargs) return response
def _request(self, method, url, data=None, **kwargs): try: response = self.session.request(method, url, data=data, **kwargs) if response.status_code == 200: return response else: try: data = response.json() except ValueError: data = None raise matchlight.error.APIError( response.status_code, response.reason, data) except requests.exceptions.RetryError: raise matchlight.error.ConnectionError( 'Matchlight API request failed with too many retries') except requests.exceptions.ConnectionError: raise matchlight.error.ConnectionError( 'Matchlight API request failed with connection error') def __repr__(self): # pragma: no cover return self.access_key