prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Support for custom authentication objects for requests module
  Hi,
  
  Several transport classes are available, one of them is "requests".
  Requests supports basic-authentication but far more than that ([0](http://docs.python-requests.org/en/latest/user/advanced/#custom-authentication)). In order to support this a few lines would need to be changed to allow for providing an authentication object ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)).
  
  I have the code ready ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)) for this and am actively using it.
  
  Would you be willing to accept this contribution ?
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `elasticsearch/connection/http_requests.py`
  Content:
  ```
  1 import time
  2 import warnings
  3 try:
  4     import requests
  5     REQUESTS_AVAILABLE = True
  6 except ImportError:
  7     REQUESTS_AVAILABLE = False
  8 
  9 from .base import Connection
  10 from ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError
  11 from ..compat import urlencode
  12 
  13 class RequestsHttpConnection(Connection):
  14     """
  15     Connection using the `requests` library.
  16 
  17     :arg http_auth: optional http auth information as either ':' separated
  18         string or a tuple
  19     :arg use_ssl: use ssl for the connection if `True`
  20     :arg verify_certs: whether to verify SSL certificates
  21     :arg ca_certs: optional path to CA bundle. By default standard requests'
  22         bundle will be used.
  23     :arg client_cert: path to the file containing the private key and the
  24         certificate
  25     """
  26     def __init__(self, host='localhost', port=9200, http_auth=None,
  27         use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None,
  28         **kwargs):
  29         if not REQUESTS_AVAILABLE:
  30             raise ImproperlyConfigured("Please install requests to use RequestsHttpConnection.")
  31 
  32         super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)
  33         self.session = requests.session()
  34         if http_auth is not None:
  35             if not isinstance(http_auth, (tuple, list)):
  36                 http_auth = http_auth.split(':', 1)
  37             http_auth = tuple(http_auth)
  38             self.session.auth = http_auth
  39         self.base_url = 'http%s://%s:%d%s' % (
  40             's' if use_ssl else '',
  41             host, port, self.url_prefix
  42         )
  43         self.session.verify = verify_certs
  44         self.session.cert = client_cert
  45         if ca_certs:
  46             if not verify_certs:
  47                 raise ImproperlyConfigured("You cannot pass CA certificates when verify SSL is off.")
  48             self.session.verify = ca_certs
  49 
  50         if use_ssl and not verify_certs:
  51             warnings.warn(
  52                 'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url)
  53 
  54     def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):
  55         url = self.base_url + url
  56         if params:
  57             url = '%s?%s' % (url, urlencode(params or {}))
  58 
  59         start = time.time()
  60         try:
  61             response = self.session.request(method, url, data=body, timeout=timeout or self.timeout)
  62             duration = time.time() - start
  63             raw_data = response.text
  64         except requests.exceptions.SSLError as e:
  65             self.log_request_fail(method, url, body, time.time() - start, exception=e)
  66             raise SSLError('N/A', str(e), e)
  67         except requests.Timeout as e:
  68             self.log_request_fail(method, url, body, time.time() - start, exception=e)
  69             raise ConnectionTimeout('TIMEOUT', str(e), e)
  70         except requests.ConnectionError as e:
  71             self.log_request_fail(method, url, body, time.time() - start, exception=e)
  72             raise ConnectionError('N/A', str(e), e)
  73 
  74         # raise errors based on http status codes, let the client handle those if needed
  75         if not (200 <= response.status_code < 300) and response.status_code not in ignore:
  76             self.log_request_fail(method, url, body, duration, response.status_code)
  77             self._raise_error(response.status_code, raw_data)
  78 
  79         self.log_request_success(method, url, response.request.path_url, body, response.status_code, raw_data, duration)
  80 
  81         return response.status_code, response.headers, raw_data
  82
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/elasticsearch/connection/http_requests.py b/elasticsearch/connection/http_requests.py
  --- a/elasticsearch/connection/http_requests.py
  +++ b/elasticsearch/connection/http_requests.py
  @@ -1,3 +1,4 @@
  +import six
   import time
   import warnings
   try:
  @@ -32,8 +33,10 @@
           super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)
           self.session = requests.session()
           if http_auth is not None:
  -            if not isinstance(http_auth, (tuple, list)):
  -                http_auth = http_auth.split(':', 1)
  +            if isinstance(http_auth, (tuple, list)):
  +                http_auth = tuple(http_auth)
  +            elif isinstance(http_auth, six.string_types):
  +                http_auth = tuple(http_auth.split(':', 1))
               http_auth = tuple(http_auth)
               self.session.auth = http_auth
           self.base_url = 'http%s://%s:%d%s' % (
  
verification_info: {"golden_diff": "diff --git a/elasticsearch/connection/http_requests.py b/elasticsearch/connection/http_requests.py\n--- a/elasticsearch/connection/http_requests.py\n+++ b/elasticsearch/connection/http_requests.py\n@@ -1,3 +1,4 @@\n+import six\n import time\n import warnings\n try:\n@@ -32,8 +33,10 @@\n         super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)\n         self.session = requests.session()\n         if http_auth is not None:\n-            if not isinstance(http_auth, (tuple, list)):\n-                http_auth = http_auth.split(':', 1)\n+            if isinstance(http_auth, (tuple, list)):\n+                http_auth = tuple(http_auth)\n+            elif isinstance(http_auth, six.string_types):\n+                http_auth = tuple(http_auth.split(':', 1))\n             http_auth = tuple(http_auth)\n             self.session.auth = http_auth\n         self.base_url = 'http%s://%s:%d%s' % (\n", "issue": "Support for custom authentication objects for requests module\nHi,\n\nSeveral transport classes are available, one of them is \"requests\".\nRequests supports basic-authentication but far more than that ([0](http://docs.python-requests.org/en/latest/user/advanced/#custom-authentication)). In order to support this a few lines would need to be changed to allow for providing an authentication object ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)).\n\nI have the code ready ([1](https://github.com/elastic/elasticsearch-py/compare/master...sim0nx:requests_custom_authentication)) for this and am actively using it.\n\nWould you be willing to accept this contribution ?\n\n", "before_files": [{"content": "import time\nimport warnings\ntry:\n    import requests\n    REQUESTS_AVAILABLE = True\nexcept ImportError:\n    REQUESTS_AVAILABLE = False\n\nfrom .base import Connection\nfrom ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError\nfrom ..compat import urlencode\n\nclass RequestsHttpConnection(Connection):\n    \"\"\"\n    Connection using the `requests` library.\n\n    :arg http_auth: optional http auth information as either ':' separated\n        string or a tuple\n    :arg use_ssl: use ssl for the connection if `True`\n    :arg verify_certs: whether to verify SSL certificates\n    :arg ca_certs: optional path to CA bundle. By default standard requests'\n        bundle will be used.\n    :arg client_cert: path to the file containing the private key and the\n        certificate\n    \"\"\"\n    def __init__(self, host='localhost', port=9200, http_auth=None,\n        use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None,\n        **kwargs):\n        if not REQUESTS_AVAILABLE:\n            raise ImproperlyConfigured(\"Please install requests to use RequestsHttpConnection.\")\n\n        super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)\n        self.session = requests.session()\n        if http_auth is not None:\n            if not isinstance(http_auth, (tuple, list)):\n                http_auth = http_auth.split(':', 1)\n            http_auth = tuple(http_auth)\n            self.session.auth = http_auth\n        self.base_url = 'http%s://%s:%d%s' % (\n            's' if use_ssl else '',\n            host, port, self.url_prefix\n        )\n        self.session.verify = verify_certs\n        self.session.cert = client_cert\n        if ca_certs:\n            if not verify_certs:\n                raise ImproperlyConfigured(\"You cannot pass CA certificates when verify SSL is off.\")\n            self.session.verify = ca_certs\n\n        if use_ssl and not verify_certs:\n            warnings.warn(\n                'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url)\n\n    def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):\n        url = self.base_url + url\n        if params:\n            url = '%s?%s' % (url, urlencode(params or {}))\n\n        start = time.time()\n        try:\n            response = self.session.request(method, url, data=body, timeout=timeout or self.timeout)\n            duration = time.time() - start\n            raw_data = response.text\n        except requests.exceptions.SSLError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise SSLError('N/A', str(e), e)\n        except requests.Timeout as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionTimeout('TIMEOUT', str(e), e)\n        except requests.ConnectionError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionError('N/A', str(e), e)\n\n        # raise errors based on http status codes, let the client handle those if needed\n        if not (200 <= response.status_code < 300) and response.status_code not in ignore:\n            self.log_request_fail(method, url, body, duration, response.status_code)\n            self._raise_error(response.status_code, raw_data)\n\n        self.log_request_success(method, url, response.request.path_url, body, response.status_code, raw_data, duration)\n\n        return response.status_code, response.headers, raw_data\n", "path": "elasticsearch/connection/http_requests.py"}], "after_files": [{"content": "import six\nimport time\nimport warnings\ntry:\n    import requests\n    REQUESTS_AVAILABLE = True\nexcept ImportError:\n    REQUESTS_AVAILABLE = False\n\nfrom .base import Connection\nfrom ..exceptions import ConnectionError, ImproperlyConfigured, ConnectionTimeout, SSLError\nfrom ..compat import urlencode\n\nclass RequestsHttpConnection(Connection):\n    \"\"\"\n    Connection using the `requests` library.\n\n    :arg http_auth: optional http auth information as either ':' separated\n        string or a tuple\n    :arg use_ssl: use ssl for the connection if `True`\n    :arg verify_certs: whether to verify SSL certificates\n    :arg ca_certs: optional path to CA bundle. By default standard requests'\n        bundle will be used.\n    :arg client_cert: path to the file containing the private key and the\n        certificate\n    \"\"\"\n    def __init__(self, host='localhost', port=9200, http_auth=None,\n        use_ssl=False, verify_certs=False, ca_certs=None, client_cert=None,\n        **kwargs):\n        if not REQUESTS_AVAILABLE:\n            raise ImproperlyConfigured(\"Please install requests to use RequestsHttpConnection.\")\n\n        super(RequestsHttpConnection, self).__init__(host= host, port=port, **kwargs)\n        self.session = requests.session()\n        if http_auth is not None:\n            if isinstance(http_auth, (tuple, list)):\n                http_auth = tuple(http_auth)\n            elif isinstance(http_auth, six.string_types):\n                http_auth = tuple(http_auth.split(':', 1))\n            http_auth = tuple(http_auth)\n            self.session.auth = http_auth\n        self.base_url = 'http%s://%s:%d%s' % (\n            's' if use_ssl else '',\n            host, port, self.url_prefix\n        )\n        self.session.verify = verify_certs\n        self.session.cert = client_cert\n        if ca_certs:\n            if not verify_certs:\n                raise ImproperlyConfigured(\"You cannot pass CA certificates when verify SSL is off.\")\n            self.session.verify = ca_certs\n\n        if use_ssl and not verify_certs:\n            warnings.warn(\n                'Connecting to %s using SSL with verify_certs=False is insecure.' % self.base_url)\n\n    def perform_request(self, method, url, params=None, body=None, timeout=None, ignore=()):\n        url = self.base_url + url\n        if params:\n            url = '%s?%s' % (url, urlencode(params or {}))\n\n        start = time.time()\n        try:\n            response = self.session.request(method, url, data=body, timeout=timeout or self.timeout)\n            duration = time.time() - start\n            raw_data = response.text\n        except requests.exceptions.SSLError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise SSLError('N/A', str(e), e)\n        except requests.Timeout as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionTimeout('TIMEOUT', str(e), e)\n        except requests.ConnectionError as e:\n            self.log_request_fail(method, url, body, time.time() - start, exception=e)\n            raise ConnectionError('N/A', str(e), e)\n\n        # raise errors based on http status codes, let the client handle those if needed\n        if not (200 <= response.status_code < 300) and response.status_code not in ignore:\n            self.log_request_fail(method, url, body, duration, response.status_code)\n            self._raise_error(response.status_code, raw_data)\n\n        self.log_request_success(method, url, response.request.path_url, body, response.status_code, raw_data, duration)\n\n        return response.status_code, response.headers, raw_data\n", "path": "elasticsearch/connection/http_requests.py"}]}