<commit_before>import requests, urllib
import collections
import json

_HTTP_GET = 0
_HTTP_POST = 1

class APIError(StandardError):
    """
    APIError contains json message indicating failure
    """
    def __init__(self, error_id, error_message, error_name, request):
        self.error_id = error_id
        self.error_message = error_message
        self.error_name = error_name
        self.request = request
        StandardError.__init__(self, error_name)

    def __str__(self):
        return 'APIError: %s: %s\n%s\nrequest: %s' % \
        (self.error_id, self.error_name, self.error_message, self.request)

def _encode_params(**kwargs):
    """
    Do url-encode parameters

    >>> _encode_params(a=1, b='R&D')
    'a=1&b=R%26D'
    >>> _encode_params(a=u'\u4e2d\u6587', b=['A', 'B', 123])
    'a=%E4%B8%AD%E6%96%87&b=A&b=B&b=123'
    """

    args = []
    for k, v in kwargs.iteritems():
        if isinstance(v, basestring):
            qv = v.encode('utf-8') if isinstance(v, unicode) else v
            args.append('%s=%s' % (k, urllib.quote(qv)))
        elif isinstance(v, collections.Iterable):
            for i in v:
                qv = i.encode('utf-8') if isinstance(i, unicode) else str(i)
                args.append('%s=%s' % (k, urllib.quote(qv)))
        else:
            qv = str(v)
            args.append('%s=%s' % (k, urllib.quote(qv)))
    return '&'.join(args)

def _encode_ids(*args):
    """
    Do url-encode resource ids
    """

    ids = []
    for v in args:
        if isinstance(v, basestring):
            qv = v.encode('utf-8') if isinstance(v, unicode) else v
            ids.append(urllib.quote(qv))
        else:
            qv = str(v)
            ids.append(urllib.quote(qv))

    return ';'.join(ids)


def _http_call(url, method, *args, **kwargs):
    params = _encode_params(**kwargs)
    ids = ''
    url_format_str = '%s%s?%s'

    if args:
        ids = _encode_ids(*args)
        url_format_str = '%s/%s?%s'

    http_url = url_format_str % (url, ids, params) if method == _HTTP_GET else url

    result = requests.get(http_url)
    result = json.loads(result.text)

    if 'error_id' in result:
        raise APIError(result['error_id'], result['error_message'],
            result['error_name'], http_url)

    return result


class Stackexchange(object):
    """
    Stackexchange uses dot notation when accessing Stackexchange API
    """

    def __init__(self, app_key, domain='api.stackexchange.com', \
        site='stackoverflow', version='2.1'):

        self.app_key = str(app_key)
        self.api_url = 'http://%s/%s/' % (domain, version)<commit_msg>Made pystex to handle ConnectionError from requests gracefully<commit_after>import requests, urllib
import collections
import json

_HTTP_GET = 0
_HTTP_POST = 1

class APIError(StandardError):
    """
    APIError contains json message indicating failure
    """
    def __init__(self, error_id, error_message, error_name, request,  *args, **kwargs):
        self.error_id = error_id
        self.error_message = error_message
        self.error_name = error_name
        self.request = request
        super(StandardError, self).__init__(*args, **kwargs)

    def __str__(self):
        return super.__str__() + \
        'APIError: %s: %s\n%s\nrequest: %s' % \
        (self.error_id, self.error_name, self.error_message, self.request)

def _encode_params(**kwargs):
    """
    Do url-encode parameters

    >>> _encode_params(a=1, b='R&D')
    'a=1&b=R%26D'
    >>> _encode_params(a=u'\u4e2d\u6587', b=['A', 'B', 123])
    'a=%E4%B8%AD%E6%96%87&b=A&b=B&b=123'
    """

    args = []
    for k, v in kwargs.iteritems():
        if isinstance(v, basestring):
            qv = v.encode('utf-8') if isinstance(v, unicode) else v
            args.append('%s=%s' % (k, urllib.quote(qv)))
        elif isinstance(v, collections.Iterable):
            for i in v:
                qv = i.encode('utf-8') if isinstance(i, unicode) else str(i)
                args.append('%s=%s' % (k, urllib.quote(qv)))
        else:
            qv = str(v)
            args.append('%s=%s' % (k, urllib.quote(qv)))
    return '&'.join(args)

def _encode_ids(*args):
    """
    Do url-encode resource ids
    """

    ids = []
    for v in args:
        if isinstance(v, basestring):
            qv = v.encode('utf-8') if isinstance(v, unicode) else v
            ids.append(urllib.quote(qv))
        else:
            qv = str(v)
            ids.append(urllib.quote(qv))

    return ';'.join(ids)


def _http_call(url, method, *args, **kwargs):
    params = _encode_params(**kwargs)
    ids = ''
    url_format_str = '%s%s?%s'

    if args:
        ids = _encode_ids(*args)
        url_format_str = '%s/%s?%s'

    http_url = url_format_str % (url, ids, params) if method == _HTTP_GET else url

    try:
        result = requests.get(http_url)
    except requests.exceptions.ConnectionError:
        raise APIError('ConnectionError', 'ConnectionError', 'ConnectionError', http_url)

    result = json.loads(result.text)
    if 'error_id' in result:
        raise APIError(result['error_id'], result['error_message'],
            result['error_name'], http_url)

    return result


class Stackexchange(object):
    """
    Stackexchange uses dot notation when accessing Stackexchange API
    """

    def __init__(self, app_key, domain='api.stackexchange.com', \
        site='stackoverflow', version='2.1'):

        self.app_key = str(app_key)
        self.api_url = 'http://%s/%s/' % (domain, version)
{'fraction_non_alphanumeric': 0.14760348583877997, 'fraction_numerical': 0.010893246187363835, 'mean_word_length': 2.5889250814332248, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5489207', 'n_tokens_mistral': 1958, 'n_tokens_neox': 1891, 'n_words': 406}