Source code for compmusic.dunya.conn

import logging
import six
from six.moves.urllib import parse as urllibparse

import requests
import requests.adapters

logger = logging.getLogger("dunya")

HOSTNAME = "https://dunya.compmusic.upf.edu"
TOKEN = None
session = requests.Session()
session.mount('http://', requests.adapters.HTTPAdapter(max_retries=5))
session.mount('https://', requests.adapters.HTTPAdapter(max_retries=5))

[docs]class HTTPError(Exception): pass
[docs]class ConnectionError(Exception): pass
[docs]def set_hostname(hostname): """ Change the hostname of the dunya API endpoint. Arguments: hostname: The new dunya hostname to set. If you want to access over http or a different port, include them in the hostname, e.g. `http://localhost:8000` """ global HOSTNAME HOSTNAME = hostname
[docs]def set_token(token): """ Set an access token. You must call this before you can make any other calls. Arguments: token: your access token """ global TOKEN TOKEN = token
def _get_paged_json(path, **kwargs): extra_headers = None if 'extra_headers' in kwargs: extra_headers = kwargs.get('extra_headers') del kwargs['extra_headers'] nxt = _make_url(path, **kwargs) logger.debug("initial paged to %s", nxt) ret = [] while nxt: res = _dunya_url_query(nxt, extra_headers=extra_headers) res = res.json() ret.extend(res.get("results", [])) nxt = res.get("next") return ret def _dunya_url_query(url, extra_headers=None): logger.debug("query to '%s'" % url) if not TOKEN: raise ConnectionError("You need to authenticate with `set_token`") headers = {"Authorization": "Token %s" % TOKEN} if extra_headers: headers.update(extra_headers) g = session.get(url, headers=headers) try: g.raise_for_status() except requests.exceptions.HTTPError as e: raise HTTPError(e) return g def _dunya_post(url, data=None, files=None): data = data or {} files = files or {} logger.debug("post to '%s'" % url) if not TOKEN: raise ConnectionError("You need to authenticate with `set_token`") headers = {"Authorization": "Token %s" % TOKEN} p = requests.post(url, headers=headers, data=data, files=files) try: p.raise_for_status() except requests.exceptions.HTTPError as e: raise HTTPError(e) return p def _make_url(path, **kwargs): if "://" in HOSTNAME: protocol, hostname = HOSTNAME.split("://") else: protocol = "http" hostname = HOSTNAME if not kwargs: kwargs = {} for key, value in kwargs.items(): if isinstance(value, six.text_type): kwargs[key] = value.encode('utf8') url = urllibparse.urlunparse(( protocol, hostname, '%s' % path, '', urllibparse.urlencode(kwargs), '' )) return url def _dunya_query_json(path, **kwargs): """Make a query to dunya and expect the results to be JSON""" g = _dunya_url_query(_make_url(path, **kwargs)) return g.json() if g else None def _dunya_query_file(path, **kwargs): """Make a query to dunya and return the raw result""" g = _dunya_url_query(_make_url(path, **kwargs)) if g: cl = g.headers.get('content-length') content = g.content if cl and int(cl) != len(content): logger.warning("Indicated content length is not the same as returned content. Some data may be missing") return content else: return None