<commit_before>import abc
import base64
import json
import logging
import sys
import types
import six
try:
    # py3
    from urllib.request import urlopen, Request
    from urllib.parse import urlencode
    from urllib.error import URLError
except ImportError:
    # py2
    from urllib import urlencode
    from urllib2 import urlopen, Request, URLError


# set default logger handler
logging.getLogger(__name__).addHandler(logging.NullHandler())


class CallFireError(Exception):
    """Exception wrapper."""
    def __init__(self, wrapped_exc, *args, **kwargs):
        self.wrapped_exc = wrapped_exc
        super(CallFireError, self).__init__(*args, **kwargs)


@six.add_metaclass(abc.ABCMeta)
class BaseRequest(object):
    """Class for preparing a customized request."""

    def __init__(self, path, query=None, body=None, **kwargs):
        self.path = path
        self.query = query
        self.body = body

    @property
    @abc.abstractmethod
    def additional_headers(self):
        """Get a dictionary with additional headers for this request."""

    @property
    @abc.abstractmethod
    def prepared_body(self):
        """The prepared body

        This method should do everything necessary in ordr for the
        underlying body to be useful with this kind of request.
        """

    def prepare(self, base_url, auth_header, method):
        """Prepare the underlying request

        The act of preparation involves transforming the body
        into the right format, setting the required headers.

        :param method: The method with which this request is going to be used
        :returns: An instance of urllib.Request.
        """

        url = '{}{}'.format(base_url, self.path)
        if self.query:
            url += '?{}'.format(urlencode(self.query))

        headers = {'Authorization': auth_header}
        headers.update(self.additional_headers)

        request = Request(url, self.prepared_body, headers)
        request.get_method = lambda: method
        return request


class JSONRequest(BaseRequest):
    """A request which knows how to process JSON payloads."""

    additional_headers = {'Content-Type': 'application/json'}

    @property
    def prepared_body(self):
        if self.body:
            return json.dumps(self.body).encode('utf-8')


class MultipartRequest(BaseRequest):
    """Request which can be used for multipart form posting."""

    def __init__(self, *args, **kwargs):
        super(MultipartRequest, self).__init__(*args, **kwargs)
        self._payload = kwargs.pop('payload', None)
        self._prepared_body = None

    @property
    def additional_headers(self):
        return {
            'Content-type': 'multipart/form-data; boundary=boundary',
            'Content-Length': len(self.prepared_body),
        }

    @staticmethod
    def generate_multipart(file_stream):
        parts = []
        boundary = 'boundary'
        part_boundary = '--' + boundary

        parts = [
            part_boundary,
            'Content-Disposition: form-data; name="file"; filename="file"'
            '\r\n',
            file_stream.read(),
            '--{}--'.format(boundary),
            '',
        ]
        return '\r\n'.join(parts)

    @property
    def prepared_body(self):
        if self._prepared_body:
            return self._prepared_body

        self._prepared_body = self.generate_multipart(self._payload)
        return self._prepared_body


class BaseAPI(object):
    #: Base API url
    BASE_URL = None
    #: Logger
    logger = logging.getLogger(__name__)

    def __init__(self, username, password, debug=False):
        """API base.

        :param username: API username
        :param password: <PASSWORD>
        :param debug: enable debug logger
        """
        self.username = username<commit_msg>Use byte strings when building the multipart form.<commit_after>import abc
import base64
import json
import logging
import sys
import types
import six
try:
    # py3
    from urllib.request import urlopen, Request
    from urllib.parse import urlencode
    from urllib.error import URLError
except ImportError:
    # py2
    from urllib import urlencode
    from urllib2 import urlopen, Request, URLError


# set default logger handler
logging.getLogger(__name__).addHandler(logging.NullHandler())


class CallFireError(Exception):
    """Exception wrapper."""
    def __init__(self, wrapped_exc, *args, **kwargs):
        self.wrapped_exc = wrapped_exc
        super(CallFireError, self).__init__(*args, **kwargs)


@six.add_metaclass(abc.ABCMeta)
class BaseRequest(object):
    """Class for preparing a customized request."""

    def __init__(self, path, query=None, body=None, **kwargs):
        self.path = path
        self.query = query
        self.body = body

    @property
    @abc.abstractmethod
    def additional_headers(self):
        """Get a dictionary with additional headers for this request."""

    @property
    @abc.abstractmethod
    def prepared_body(self):
        """The prepared body

        This method should do everything necessary in ordr for the
        underlying body to be useful with this kind of request.
        """

    def prepare(self, base_url, auth_header, method):
        """Prepare the underlying request

        The act of preparation involves transforming the body
        into the right format, setting the required headers.

        :param method: The method with which this request is going to be used
        :returns: An instance of urllib.Request.
        """

        url = '{}{}'.format(base_url, self.path)
        if self.query:
            url += '?{}'.format(urlencode(self.query))

        headers = {'Authorization': auth_header}
        headers.update(self.additional_headers)

        request = Request(url, self.prepared_body, headers)
        request.get_method = lambda: method
        return request


class JSONRequest(BaseRequest):
    """A request which knows how to process JSON payloads."""

    additional_headers = {'Content-Type': 'application/json'}

    @property
    def prepared_body(self):
        if self.body:
            return json.dumps(self.body).encode('utf-8')


class MultipartRequest(BaseRequest):
    """Request which can be used for multipart form posting."""

    def __init__(self, *args, **kwargs):
        super(MultipartRequest, self).__init__(*args, **kwargs)
        self._payload = kwargs.pop('payload', None)
        self._prepared_body = None

    @property
    def additional_headers(self):
        return {
            'Content-type': 'multipart/form-data; boundary=boundary',
            'Content-Length': len(self.prepared_body),
        }

    @staticmethod
    def generate_multipart(file_stream):
        boundary = b'boundary'
        part_boundary = b'--' + boundary

        parts = [
            part_boundary,
            b'Content-Disposition: form-data; name="file"; filename="file"'
            b'\r\n',
            file_stream.read(),
            b'--' + boundary + b'--',
            b'',
        ]
        return b'\r\n'.join(parts)

    @property
    def prepared_body(self):
        if self._prepared_body:
            return self._prepared_body

        self._prepared_body = self.generate_multipart(self._payload)
        return self._prepared_body


class BaseAPI(object):
    #: Base API url
    BASE_URL = None
    #: Logger
    logger = logging.getLogger(__name__)

    def __init__(self, username, password, debug=False):
        """API base.

        :param username: API username
        :param password: <PASSWORD>
        :param debug: enable debug logger
        """
        self.username = username
{'fraction_non_alphanumeric': 0.10181675597961051, 'fraction_numerical': 0.0015684224284407268, 'mean_word_length': 2.597555242125059, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '3463739', 'n_tokens_mistral': 2142, 'n_tokens_neox': 2051, 'n_words': 607}