# Path: treq/client.py
# class HTTPClient(object):
#     def __init__(self, agent):
#         self._agent = agent
# 
#     def get(self, url, **kwargs):
#         return self.request('GET', url, **kwargs)
# 
#     def put(self, url, data=None, **kwargs):
#         return self.request('PUT', url, data=data, **kwargs)
# 
#     def patch(self, url, data=None, **kwargs):
#         return self.request('PATCH', url, data=data, **kwargs)
# 
#     def post(self, url, data=None, **kwargs):
#         return self.request('POST', url, data=data, **kwargs)
# 
#     def head(self, url, **kwargs):
#         return self.request('HEAD', url, **kwargs)
# 
#     def delete(self, url, **kwargs):
#         return self.request('DELETE', url, **kwargs)
# 
#     def request(self, method, url, **kwargs):
#         method = method.upper()
# 
#         # Join parameters provided in the URL
#         # and the ones passed as argument.
#         params = kwargs.get('params')
#         if params:
#             url = _combine_query_params(url, params)
# 
#         # Convert headers dictionary to
#         # twisted raw headers format.
#         headers = kwargs.get('headers')
#         if headers:
#             if isinstance(headers, dict):
#                 h = Headers({})
#                 for k, v in headers.iteritems():
#                     if isinstance(v, str):
#                         h.addRawHeader(k, v)
#                     else:
#                         h.setRawHeaders(k, v)
# 
#                 headers = h
#         else:
#             headers = Headers({})
# 
#         # Here we choose a right producer
#         # based on the parameters passed in.
#         bodyProducer = None
#         data = kwargs.get('data')
#         files = kwargs.get('files')
#         if files:
#             # If the files keyword is present we will issue a
#             # multipart/form-data request as it suits better for cases
#             # with files and/or large objects.
#             files = list(_convert_files(files))
#             boundary = uuid.uuid4()
#             headers.setRawHeaders(
#                 'content-type', [
#                     'multipart/form-data; boundary=%s' % (boundary,)])
#             if data:
#                 data = _convert_params(data)
#             else:
#                 data = []
# 
#             bodyProducer = multipart.MultiPartProducer(
#                 data + files, boundary=boundary)
#         elif data:
#             # Otherwise stick to x-www-form-urlencoded format
#             # as it's generally faster for smaller requests.
#             if isinstance(data, (dict, list, tuple)):
#                 headers.setRawHeaders(
#                     'content-type', ['application/x-www-form-urlencoded'])
#                 data = urlencode(data, doseq=True)
#             bodyProducer = IBodyProducer(data)
# 
#         wrapped_agent = self._agent
# 
#         if kwargs.get('allow_redirects', True):
#             wrapped_agent = RedirectAgent(wrapped_agent)
# 
#         wrapped_agent = ContentDecoderAgent(wrapped_agent,
#                                             [('gzip', GzipDecoder)])
# 
#         auth = kwargs.get('auth')
#         if auth:
#             wrapped_agent = add_auth(wrapped_agent, auth)
# 
#         d = wrapped_agent.request(
#             method, url, headers=headers,
#             bodyProducer=bodyProducer)
# 
#         timeout = kwargs.get('timeout')
#         if timeout:
#             delayedCall = default_reactor(kwargs.get('reactor')).callLater(
#                 timeout, d.cancel)
# 
#             def gotResult(result):
#                 if delayedCall.active():
#                     delayedCall.cancel()
#                 return result
# 
#             d.addBoth(gotResult)
# 
#         if not kwargs.get('unbuffered', False):
#             d.addCallback(_BufferedResponse)
# 
#         return d.addCallback(_Response)


from twisted.web.client import Agent
from treq.client import HTTPClient
from treq._utils import default_pool, default_reactor
    :type data: str, file-like, IBodyProducer, or None

    :param reactor: Optional twisted reactor.

    :param bool persistent: Use persistent HTTP connections.  Default: ``True``
    :param bool allow_redirects: Follow HTTP redirects.  Default: ``True``

    :param auth: HTTP Basic Authentication information.
    :type auth: tuple of ('username', 'password').

    :param int timeout: Request timeout seconds. If a response is not
        received within this timeframe, a connection is aborted with
        ``CancelledError``.

    :rtype: Deferred that fires with an IResponse provider.

    """
    return _client(**kwargs).request(method, url, **kwargs)


#
# Private API
#

def _client(*args, **kwargs):
    reactor = default_reactor(kwargs.get('reactor'))
    pool = default_pool(reactor,
                        kwargs.get('pool'),
                        kwargs.get('persistent'))
    agent = Agent(reactor, pool=pool)

# Path: treq/client.py
# class HTTPClient(object):
#     def __init__(self, agent):
#         self._agent = agent
# 
#     def get(self, url, **kwargs):
#         return self.request('GET', url, **kwargs)
# 
#     def put(self, url, data=None, **kwargs):
#         return self.request('PUT', url, data=data, **kwargs)
# 
#     def patch(self, url, data=None, **kwargs):
#         return self.request('PATCH', url, data=data, **kwargs)
# 
#     def post(self, url, data=None, **kwargs):
#         return self.request('POST', url, data=data, **kwargs)
# 
#     def head(self, url, **kwargs):
#         return self.request('HEAD', url, **kwargs)
# 
#     def delete(self, url, **kwargs):
#         return self.request('DELETE', url, **kwargs)
# 
#     def request(self, method, url, **kwargs):
#         method = method.upper()
# 
#         # Join parameters provided in the URL
#         # and the ones passed as argument.
#         params = kwargs.get('params')
#         if params:
#             url = _combine_query_params(url, params)
# 
#         # Convert headers dictionary to
#         # twisted raw headers format.
#         headers = kwargs.get('headers')
#         if headers:
#             if isinstance(headers, dict):
#                 h = Headers({})
#                 for k, v in headers.iteritems():
#                     if isinstance(v, str):
#                         h.addRawHeader(k, v)
#                     else:
#                         h.setRawHeaders(k, v)
# 
#                 headers = h
#         else:
#             headers = Headers({})
# 
#         # Here we choose a right producer
#         # based on the parameters passed in.
#         bodyProducer = None
#         data = kwargs.get('data')
#         files = kwargs.get('files')
#         if files:
#             # If the files keyword is present we will issue a
#             # multipart/form-data request as it suits better for cases
#             # with files and/or large objects.
#             files = list(_convert_files(files))
#             boundary = uuid.uuid4()
#             headers.setRawHeaders(
#                 'content-type', [
#                     'multipart/form-data; boundary=%s' % (boundary,)])
#             if data:
#                 data = _convert_params(data)
#             else:
#                 data = []
# 
#             bodyProducer = multipart.MultiPartProducer(
#                 data + files, boundary=boundary)
#         elif data:
#             # Otherwise stick to x-www-form-urlencoded format
#             # as it's generally faster for smaller requests.
#             if isinstance(data, (dict, list, tuple)):
#                 headers.setRawHeaders(
#                     'content-type', ['application/x-www-form-urlencoded'])
#                 data = urlencode(data, doseq=True)
#             bodyProducer = IBodyProducer(data)
# 
#         wrapped_agent = self._agent
# 
#         if kwargs.get('allow_redirects', True):
#             wrapped_agent = RedirectAgent(wrapped_agent)
# 
#         wrapped_agent = ContentDecoderAgent(wrapped_agent,
#                                             [('gzip', GzipDecoder)])
# 
#         auth = kwargs.get('auth')
#         if auth:
#             wrapped_agent = add_auth(wrapped_agent, auth)
# 
#         d = wrapped_agent.request(
#             method, url, headers=headers,
#             bodyProducer=bodyProducer)
# 
#         timeout = kwargs.get('timeout')
#         if timeout:
#             delayedCall = default_reactor(kwargs.get('reactor')).callLater(
#                 timeout, d.cancel)
# 
#             def gotResult(result):
#                 if delayedCall.active():
#                     delayedCall.cancel()
#                 return result
# 
#             d.addBoth(gotResult)
# 
#         if not kwargs.get('unbuffered', False):
#             d.addCallback(_BufferedResponse)
# 
#         return d.addCallback(_Response)


# Path: treq/api.py
from twisted.web.client import Agent
from treq.client import HTTPClient
from treq._utils import default_pool, default_reactor

    :type data: str, file-like, IBodyProducer, or None

    :param reactor: Optional twisted reactor.

    :param bool persistent: Use persistent HTTP connections.  Default: ``True``
    :param bool allow_redirects: Follow HTTP redirects.  Default: ``True``

    :param auth: HTTP Basic Authentication information.
    :type auth: tuple of ('username', 'password').

    :param int timeout: Request timeout seconds. If a response is not
        received within this timeframe, a connection is aborted with
        ``CancelledError``.

    :rtype: Deferred that fires with an IResponse provider.

    """
    return _client(**kwargs).request(method, url, **kwargs)


#
# Private API
#

def _client(*args, **kwargs):
    reactor = default_reactor(kwargs.get('reactor'))
    pool = default_pool(reactor,
                        kwargs.get('pool'),
                        kwargs.get('persistent'))
    agent = Agent(reactor, pool=pool)

    return HTTPClient(agent)