We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Stream TypeError: 'str' does not support the buffer interface
Hello.

When I try [this](http://nbviewer.ipython.org/github/plotly/python-user-guide/blob/master/s7_streaming/s7_streaming_p1-first-stream.ipynb) code I get an error in rendering Cell number 11:

```
TypeError: 'str' does not support the buffer interface
```

I guess it's because I'm running `Python 3.4`. Since Python 3 there is necessary to treat bytes and unicodes differently.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plotly/plotly/chunked_requests/chunked_request.py`
Content:
```
1 import time
2 import six
3 from six.moves import http_client
4 
5 
6 class Stream:
7     def __init__(self, server, port=80, headers={}):
8         ''' Initialize a stream object and an HTTP Connection
9         with chunked Transfer-Encoding to server:port with optional headers.
10         '''
11         self.maxtries = 5
12         self._tries = 0
13         self._delay = 1
14         self._closed = False
15         self._server = server
16         self._port = port
17         self._headers = headers
18         self._connect()
19 
20     def write(self, data, reconnect_on=('', 200, )):
21         ''' Send `data` to the server in chunk-encoded form.
22         Check the connection before writing and reconnect
23         if disconnected and if the response status code is in `reconnect_on`.
24 
25         The response may either be an HTTPResponse object or an empty string.
26         '''
27 
28         if not self._isconnected():
29 
30             # Attempt to get the response.
31             response = self._getresponse()
32 
33             # Reconnect depending on the status code.
34             if ((response == '' and '' in reconnect_on) or
35                 (response and isinstance(response, http_client.HTTPResponse) and
36                  response.status in reconnect_on)):
37                 self._reconnect()
38 
39             elif response and isinstance(response, http_client.HTTPResponse):
40                 # If an HTTPResponse was recieved then
41                 # make the users aware instead of
42                 # auto-reconnecting in case the
43                 # server is responding with an important
44                 # message that might prevent
45                 # future requests from going through,
46                 # like Invalid Credentials.
47                 # This allows the user to determine when
48                 # to reconnect.
49                 raise Exception("Server responded with "
50                                 "status code: {status_code}\n"
51                                 "and message: {msg}."
52                                 .format(status_code=response.status,
53                                         msg=response.read()))
54 
55             elif response == '':
56                 raise Exception("Attempted to write but socket "
57                                 "was not connected.")
58 
59         try:
60             msg = data
61             msglen = format(len(msg), 'x')  # msg length in hex
62             # Send the message in chunk-encoded form
63             self._conn.send('{msglen}\r\n{msg}\r\n'
64                             .format(msglen=msglen, msg=msg))
65         except http_client.socket.error:
66             self._reconnect()
67             self.write(data)
68 
69     def _connect(self):
70         ''' Initialize an HTTP connection with chunked Transfer-Encoding
71         to server:port with optional headers.
72         '''
73         server = self._server
74         port = self._port
75         headers = self._headers
76         self._conn = http_client.HTTPConnection(server, port)
77 
78         self._conn.putrequest('POST', '/')
79         self._conn.putheader('Transfer-Encoding', 'chunked')
80         for header in headers:
81             self._conn.putheader(header, headers[header])
82         self._conn.endheaders()
83 
84         # Set blocking to False prevents recv
85         # from blocking while waiting for a response.
86         self._conn.sock.setblocking(False)
87         self._bytes = ''
88         self._reset_retries()
89         time.sleep(0.5)
90 
91     def close(self):
92         ''' Close the connection to server.
93 
94         If available, return a http_client.HTTPResponse object.
95 
96         Closing the connection involves sending the
97         Transfer-Encoding terminating bytes.
98         '''
99         self._reset_retries()
100         self._closed = True
101 
102         # Chunked-encoded posts are terminated with '0\r\n\r\n'
103         # For some reason, either Python or node.js seems to
104         # require an extra \r\n.
105         try:
106             self._conn.send('\r\n0\r\n\r\n')
107         except http_client.socket.error:
108             # In case the socket has already been closed
109             return ''
110 
111         return self._getresponse()
112 
113     def _getresponse(self):
114         ''' Read from recv and return a HTTPResponse object if possible.
115         Either
116         1 - The client has succesfully closed the connection: Return ''
117         2 - The server has already closed the connection: Return the response
118             if possible.
119         '''
120         # Wait for a response
121         self._conn.sock.setblocking(True)
122         # Parse the response
123         response = self._bytes
124         while True:
125             try:
126                 bytes = self._conn.sock.recv(1)
127             except http_client.socket.error:
128                 # For error 54: Connection reset by peer
129                 # (and perhaps others)
130                 return ''
131             if bytes == '':
132                 break
133             else:
134                 response += bytes
135         # Set recv to be non-blocking again
136         self._conn.sock.setblocking(False)
137 
138         # Convert the response string to a http_client.HTTPResponse
139         # object with a bit of a hack
140         if response != '':
141             # Taken from
142             # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html
143             try:
144                 response = http_client.HTTPResponse(_FakeSocket(response))
145                 response.begin()
146             except:
147                 # Bad headers ... etc.
148                 response = ''
149         return response
150 
151     def _isconnected(self):
152         ''' Return True if the socket is still connected
153         to the server, False otherwise.
154 
155         This check is done in 3 steps:
156         1 - Check if we have closed the connection
157         2 - Check if the original socket connection failed
158         3 - Check if the server has returned any data. If they have,
159             assume that the server closed the response after they sent
160             the data, i.e. that the data was the HTTP response.
161         '''
162 
163         # 1 - check if we've closed the connection.
164         if self._closed:
165             return False
166 
167         # 2 - Check if the original socket connection failed
168         # If this failed, then no socket was initialized
169         if self._conn.sock is None:
170             return False
171 
172         try:
173             # 3 - Check if the server has returned any data.
174             # If they have, then start to store the response
175             # in _bytes.
176             self._bytes = ''
177             self._bytes = self._conn.sock.recv(1)
178             return False
179         except http_client.socket.error as e:
180             # Check why recv failed
181             # Windows machines are the error codes
182             # that start with 1
183             # (http://msdn.microsoft.com/en-ca/library/windows/desktop/ms740668(v=vs.85).aspx)
184             if e.errno == 35 or e.errno == 10035:
185                 # This is the "Resource temporarily unavailable" error
186                 # which is thrown cuz there was nothing to receive, i.e.
187                 # the server hasn't returned a response yet.
188                 # This is a non-fatal error and the operation
189                 # should be tried again.
190                 # So, assume that the connection is still open.
191                 return True
192             elif e.errno == 54 or e.errno == 10054:
193                 # This is the "Connection reset by peer" error
194                 # which is thrown cuz the server reset the
195                 # socket, so the connection is closed.
196                 return False
197             elif e.errno == 11:
198                 # This is the "Resource temporarily unavailable" error
199                 # which happens because the "operation would have blocked
200                 # but nonblocking operation was requested".
201                 # We require non-blocking reading of this socket because
202                 # we don't want to wait around for a response, we just
203                 # want to see if a response is currently available. So
204                 # let's just assume that we're still connected and
205                 # hopefully recieve some data on the next try.
206                 return True
207             else:
208                 # Unknown scenario
209                 raise e
210 
211     def _reconnect(self):
212         ''' Connect if disconnected.
213         Retry self.maxtries times with delays
214         '''
215         if not self._isconnected():
216             try:
217                 self._connect()
218             except http_client.socket.error as e:
219                 # Attempt to reconnect if the connection was refused
220                 if e.errno == 61 or e.errno == 10061:
221                     # errno 61 is the "Connection Refused" error
222                     time.sleep(self._delay)
223                     self._delay += self._delay  # fibonacii delays
224                     self._tries += 1
225                     if self._tries < self.maxtries:
226                         self._reconnect()
227                     else:
228                         self._reset_retries()
229                         raise e
230                 else:
231                     # Unknown scenario
232                     raise e
233 
234         # Reconnect worked - reset _closed
235         self._closed = False
236 
237     def _reset_retries(self):
238         ''' Reset the connect counters and delays
239         '''
240         self._tries = 0
241         self._delay = 1
242 
243 
244 class _FakeSocket(six.StringIO):
245     # Used to construct a http_client.HTTPResponse object
246     # from a string.
247     # Thx to: http://pythonwise.blogspot.ca/2010/02/parse-http-response.html
248     def makefile(self, *args, **kwargs):
249         return self
250
```
--- 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()

```

diff --git a/plotly/plotly/chunked_requests/chunked_request.py b/plotly/plotly/chunked_requests/chunked_request.py
--- a/plotly/plotly/chunked_requests/chunked_request.py
+++ b/plotly/plotly/chunked_requests/chunked_request.py
@@ -61,7 +61,7 @@
             msglen = format(len(msg), 'x')  # msg length in hex
             # Send the message in chunk-encoded form
             self._conn.send('{msglen}\r\n{msg}\r\n'
-                            .format(msglen=msglen, msg=msg))
+                            .format(msglen=msglen, msg=msg).encode('utf-8'))
         except http_client.socket.error:
             self._reconnect()
             self.write(data)
@@ -84,7 +84,7 @@
         # Set blocking to False prevents recv
         # from blocking while waiting for a response.
         self._conn.sock.setblocking(False)
-        self._bytes = ''
+        self._bytes = six.b('')
         self._reset_retries()
         time.sleep(0.5)
 
@@ -103,7 +103,7 @@
         # For some reason, either Python or node.js seems to
         # require an extra \r\n.
         try:
-            self._conn.send('\r\n0\r\n\r\n')
+            self._conn.send('\r\n0\r\n\r\n'.encode('utf-8'))
         except http_client.socket.error:
             # In case the socket has already been closed
             return ''
@@ -123,21 +123,21 @@
         response = self._bytes
         while True:
             try:
-                bytes = self._conn.sock.recv(1)
+                _bytes = self._conn.sock.recv(1)
             except http_client.socket.error:
                 # For error 54: Connection reset by peer
                 # (and perhaps others)
-                return ''
-            if bytes == '':
+                return six.b('')
+            if _bytes == six.b(''):
                 break
             else:
-                response += bytes
+                response += _bytes
         # Set recv to be non-blocking again
         self._conn.sock.setblocking(False)
 
         # Convert the response string to a http_client.HTTPResponse
         # object with a bit of a hack
-        if response != '':
+        if response != six.b(''):
             # Taken from
             # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html
             try:
@@ -145,7 +145,7 @@
                 response.begin()
             except:
                 # Bad headers ... etc.
-                response = ''
+                response = six.b('')
         return response
 
     def _isconnected(self):
@@ -173,7 +173,7 @@
             # 3 - Check if the server has returned any data.
             # If they have, then start to store the response
             # in _bytes.
-            self._bytes = ''
+            self._bytes = six.b('')
             self._bytes = self._conn.sock.recv(1)
             return False
         except http_client.socket.error as e:

{"golden_diff": "diff --git a/plotly/plotly/chunked_requests/chunked_request.py b/plotly/plotly/chunked_requests/chunked_request.py\n--- a/plotly/plotly/chunked_requests/chunked_request.py\n+++ b/plotly/plotly/chunked_requests/chunked_request.py\n@@ -61,7 +61,7 @@\n             msglen = format(len(msg), 'x')  # msg length in hex\n             # Send the message in chunk-encoded form\n             self._conn.send('{msglen}\\r\\n{msg}\\r\\n'\n-                            .format(msglen=msglen, msg=msg))\n+                            .format(msglen=msglen, msg=msg).encode('utf-8'))\n         except http_client.socket.error:\n             self._reconnect()\n             self.write(data)\n@@ -84,7 +84,7 @@\n         # Set blocking to False prevents recv\n         # from blocking while waiting for a response.\n         self._conn.sock.setblocking(False)\n-        self._bytes = ''\n+        self._bytes = six.b('')\n         self._reset_retries()\n         time.sleep(0.5)\n \n@@ -103,7 +103,7 @@\n         # For some reason, either Python or node.js seems to\n         # require an extra \\r\\n.\n         try:\n-            self._conn.send('\\r\\n0\\r\\n\\r\\n')\n+            self._conn.send('\\r\\n0\\r\\n\\r\\n'.encode('utf-8'))\n         except http_client.socket.error:\n             # In case the socket has already been closed\n             return ''\n@@ -123,21 +123,21 @@\n         response = self._bytes\n         while True:\n             try:\n-                bytes = self._conn.sock.recv(1)\n+                _bytes = self._conn.sock.recv(1)\n             except http_client.socket.error:\n                 # For error 54: Connection reset by peer\n                 # (and perhaps others)\n-                return ''\n-            if bytes == '':\n+                return six.b('')\n+            if _bytes == six.b(''):\n                 break\n             else:\n-                response += bytes\n+                response += _bytes\n         # Set recv to be non-blocking again\n         self._conn.sock.setblocking(False)\n \n         # Convert the response string to a http_client.HTTPResponse\n         # object with a bit of a hack\n-        if response != '':\n+        if response != six.b(''):\n             # Taken from\n             # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html\n             try:\n@@ -145,7 +145,7 @@\n                 response.begin()\n             except:\n                 # Bad headers ... etc.\n-                response = ''\n+                response = six.b('')\n         return response\n \n     def _isconnected(self):\n@@ -173,7 +173,7 @@\n             # 3 - Check if the server has returned any data.\n             # If they have, then start to store the response\n             # in _bytes.\n-            self._bytes = ''\n+            self._bytes = six.b('')\n             self._bytes = self._conn.sock.recv(1)\n             return False\n         except http_client.socket.error as e:\n", "issue": "Stream TypeError: 'str' does not support the buffer interface\nHello.\n\nWhen I try [this](http://nbviewer.ipython.org/github/plotly/python-user-guide/blob/master/s7_streaming/s7_streaming_p1-first-stream.ipynb) code I get an error in rendering Cell number 11:\n\n```\nTypeError: 'str' does not support the buffer interface\n```\n\nI guess it's because I'm running `Python 3.4`. Since Python 3 there is necessary to treat bytes and unicodes differently.\n\n", "before_files": [{"content": "import time\nimport six\nfrom six.moves import http_client\n\n\nclass Stream:\n    def __init__(self, server, port=80, headers={}):\n        ''' Initialize a stream object and an HTTP Connection\n        with chunked Transfer-Encoding to server:port with optional headers.\n        '''\n        self.maxtries = 5\n        self._tries = 0\n        self._delay = 1\n        self._closed = False\n        self._server = server\n        self._port = port\n        self._headers = headers\n        self._connect()\n\n    def write(self, data, reconnect_on=('', 200, )):\n        ''' Send `data` to the server in chunk-encoded form.\n        Check the connection before writing and reconnect\n        if disconnected and if the response status code is in `reconnect_on`.\n\n        The response may either be an HTTPResponse object or an empty string.\n        '''\n\n        if not self._isconnected():\n\n            # Attempt to get the response.\n            response = self._getresponse()\n\n            # Reconnect depending on the status code.\n            if ((response == '' and '' in reconnect_on) or\n                (response and isinstance(response, http_client.HTTPResponse) and\n                 response.status in reconnect_on)):\n                self._reconnect()\n\n            elif response and isinstance(response, http_client.HTTPResponse):\n                # If an HTTPResponse was recieved then\n                # make the users aware instead of\n                # auto-reconnecting in case the\n                # server is responding with an important\n                # message that might prevent\n                # future requests from going through,\n                # like Invalid Credentials.\n                # This allows the user to determine when\n                # to reconnect.\n                raise Exception(\"Server responded with \"\n                                \"status code: {status_code}\\n\"\n                                \"and message: {msg}.\"\n                                .format(status_code=response.status,\n                                        msg=response.read()))\n\n            elif response == '':\n                raise Exception(\"Attempted to write but socket \"\n                                \"was not connected.\")\n\n        try:\n            msg = data\n            msglen = format(len(msg), 'x')  # msg length in hex\n            # Send the message in chunk-encoded form\n            self._conn.send('{msglen}\\r\\n{msg}\\r\\n'\n                            .format(msglen=msglen, msg=msg))\n        except http_client.socket.error:\n            self._reconnect()\n            self.write(data)\n\n    def _connect(self):\n        ''' Initialize an HTTP connection with chunked Transfer-Encoding\n        to server:port with optional headers.\n        '''\n        server = self._server\n        port = self._port\n        headers = self._headers\n        self._conn = http_client.HTTPConnection(server, port)\n\n        self._conn.putrequest('POST', '/')\n        self._conn.putheader('Transfer-Encoding', 'chunked')\n        for header in headers:\n            self._conn.putheader(header, headers[header])\n        self._conn.endheaders()\n\n        # Set blocking to False prevents recv\n        # from blocking while waiting for a response.\n        self._conn.sock.setblocking(False)\n        self._bytes = ''\n        self._reset_retries()\n        time.sleep(0.5)\n\n    def close(self):\n        ''' Close the connection to server.\n\n        If available, return a http_client.HTTPResponse object.\n\n        Closing the connection involves sending the\n        Transfer-Encoding terminating bytes.\n        '''\n        self._reset_retries()\n        self._closed = True\n\n        # Chunked-encoded posts are terminated with '0\\r\\n\\r\\n'\n        # For some reason, either Python or node.js seems to\n        # require an extra \\r\\n.\n        try:\n            self._conn.send('\\r\\n0\\r\\n\\r\\n')\n        except http_client.socket.error:\n            # In case the socket has already been closed\n            return ''\n\n        return self._getresponse()\n\n    def _getresponse(self):\n        ''' Read from recv and return a HTTPResponse object if possible.\n        Either\n        1 - The client has succesfully closed the connection: Return ''\n        2 - The server has already closed the connection: Return the response\n            if possible.\n        '''\n        # Wait for a response\n        self._conn.sock.setblocking(True)\n        # Parse the response\n        response = self._bytes\n        while True:\n            try:\n                bytes = self._conn.sock.recv(1)\n            except http_client.socket.error:\n                # For error 54: Connection reset by peer\n                # (and perhaps others)\n                return ''\n            if bytes == '':\n                break\n            else:\n                response += bytes\n        # Set recv to be non-blocking again\n        self._conn.sock.setblocking(False)\n\n        # Convert the response string to a http_client.HTTPResponse\n        # object with a bit of a hack\n        if response != '':\n            # Taken from\n            # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html\n            try:\n                response = http_client.HTTPResponse(_FakeSocket(response))\n                response.begin()\n            except:\n                # Bad headers ... etc.\n                response = ''\n        return response\n\n    def _isconnected(self):\n        ''' Return True if the socket is still connected\n        to the server, False otherwise.\n\n        This check is done in 3 steps:\n        1 - Check if we have closed the connection\n        2 - Check if the original socket connection failed\n        3 - Check if the server has returned any data. If they have,\n            assume that the server closed the response after they sent\n            the data, i.e. that the data was the HTTP response.\n        '''\n\n        # 1 - check if we've closed the connection.\n        if self._closed:\n            return False\n\n        # 2 - Check if the original socket connection failed\n        # If this failed, then no socket was initialized\n        if self._conn.sock is None:\n            return False\n\n        try:\n            # 3 - Check if the server has returned any data.\n            # If they have, then start to store the response\n            # in _bytes.\n            self._bytes = ''\n            self._bytes = self._conn.sock.recv(1)\n            return False\n        except http_client.socket.error as e:\n            # Check why recv failed\n            # Windows machines are the error codes\n            # that start with 1\n            # (http://msdn.microsoft.com/en-ca/library/windows/desktop/ms740668(v=vs.85).aspx)\n            if e.errno == 35 or e.errno == 10035:\n                # This is the \"Resource temporarily unavailable\" error\n                # which is thrown cuz there was nothing to receive, i.e.\n                # the server hasn't returned a response yet.\n                # This is a non-fatal error and the operation\n                # should be tried again.\n                # So, assume that the connection is still open.\n                return True\n            elif e.errno == 54 or e.errno == 10054:\n                # This is the \"Connection reset by peer\" error\n                # which is thrown cuz the server reset the\n                # socket, so the connection is closed.\n                return False\n            elif e.errno == 11:\n                # This is the \"Resource temporarily unavailable\" error\n                # which happens because the \"operation would have blocked\n                # but nonblocking operation was requested\".\n                # We require non-blocking reading of this socket because\n                # we don't want to wait around for a response, we just\n                # want to see if a response is currently available. So\n                # let's just assume that we're still connected and\n                # hopefully recieve some data on the next try.\n                return True\n            else:\n                # Unknown scenario\n                raise e\n\n    def _reconnect(self):\n        ''' Connect if disconnected.\n        Retry self.maxtries times with delays\n        '''\n        if not self._isconnected():\n            try:\n                self._connect()\n            except http_client.socket.error as e:\n                # Attempt to reconnect if the connection was refused\n                if e.errno == 61 or e.errno == 10061:\n                    # errno 61 is the \"Connection Refused\" error\n                    time.sleep(self._delay)\n                    self._delay += self._delay  # fibonacii delays\n                    self._tries += 1\n                    if self._tries < self.maxtries:\n                        self._reconnect()\n                    else:\n                        self._reset_retries()\n                        raise e\n                else:\n                    # Unknown scenario\n                    raise e\n\n        # Reconnect worked - reset _closed\n        self._closed = False\n\n    def _reset_retries(self):\n        ''' Reset the connect counters and delays\n        '''\n        self._tries = 0\n        self._delay = 1\n\n\nclass _FakeSocket(six.StringIO):\n    # Used to construct a http_client.HTTPResponse object\n    # from a string.\n    # Thx to: http://pythonwise.blogspot.ca/2010/02/parse-http-response.html\n    def makefile(self, *args, **kwargs):\n        return self\n", "path": "plotly/plotly/chunked_requests/chunked_request.py"}], "after_files": [{"content": "import time\nimport six\nfrom six.moves import http_client\n\n\nclass Stream:\n    def __init__(self, server, port=80, headers={}):\n        ''' Initialize a stream object and an HTTP Connection\n        with chunked Transfer-Encoding to server:port with optional headers.\n        '''\n        self.maxtries = 5\n        self._tries = 0\n        self._delay = 1\n        self._closed = False\n        self._server = server\n        self._port = port\n        self._headers = headers\n        self._connect()\n\n    def write(self, data, reconnect_on=('', 200, )):\n        ''' Send `data` to the server in chunk-encoded form.\n        Check the connection before writing and reconnect\n        if disconnected and if the response status code is in `reconnect_on`.\n\n        The response may either be an HTTPResponse object or an empty string.\n        '''\n\n        if not self._isconnected():\n\n            # Attempt to get the response.\n            response = self._getresponse()\n\n            # Reconnect depending on the status code.\n            if ((response == '' and '' in reconnect_on) or\n                (response and isinstance(response, http_client.HTTPResponse) and\n                 response.status in reconnect_on)):\n                self._reconnect()\n\n            elif response and isinstance(response, http_client.HTTPResponse):\n                # If an HTTPResponse was recieved then\n                # make the users aware instead of\n                # auto-reconnecting in case the\n                # server is responding with an important\n                # message that might prevent\n                # future requests from going through,\n                # like Invalid Credentials.\n                # This allows the user to determine when\n                # to reconnect.\n                raise Exception(\"Server responded with \"\n                                \"status code: {status_code}\\n\"\n                                \"and message: {msg}.\"\n                                .format(status_code=response.status,\n                                        msg=response.read()))\n\n            elif response == '':\n                raise Exception(\"Attempted to write but socket \"\n                                \"was not connected.\")\n\n        try:\n            msg = data\n            msglen = format(len(msg), 'x')  # msg length in hex\n            # Send the message in chunk-encoded form\n            self._conn.send('{msglen}\\r\\n{msg}\\r\\n'\n                            .format(msglen=msglen, msg=msg).encode('utf-8'))\n        except http_client.socket.error:\n            self._reconnect()\n            self.write(data)\n\n    def _connect(self):\n        ''' Initialize an HTTP connection with chunked Transfer-Encoding\n        to server:port with optional headers.\n        '''\n        server = self._server\n        port = self._port\n        headers = self._headers\n        self._conn = http_client.HTTPConnection(server, port)\n\n        self._conn.putrequest('POST', '/')\n        self._conn.putheader('Transfer-Encoding', 'chunked')\n        for header in headers:\n            self._conn.putheader(header, headers[header])\n        self._conn.endheaders()\n\n        # Set blocking to False prevents recv\n        # from blocking while waiting for a response.\n        self._conn.sock.setblocking(False)\n        self._bytes = six.b('')\n        self._reset_retries()\n        time.sleep(0.5)\n\n    def close(self):\n        ''' Close the connection to server.\n\n        If available, return a http_client.HTTPResponse object.\n\n        Closing the connection involves sending the\n        Transfer-Encoding terminating bytes.\n        '''\n        self._reset_retries()\n        self._closed = True\n\n        # Chunked-encoded posts are terminated with '0\\r\\n\\r\\n'\n        # For some reason, either Python or node.js seems to\n        # require an extra \\r\\n.\n        try:\n            self._conn.send('\\r\\n0\\r\\n\\r\\n'.encode('utf-8'))\n        except http_client.socket.error:\n            # In case the socket has already been closed\n            return ''\n\n        return self._getresponse()\n\n    def _getresponse(self):\n        ''' Read from recv and return a HTTPResponse object if possible.\n        Either\n        1 - The client has succesfully closed the connection: Return ''\n        2 - The server has already closed the connection: Return the response\n            if possible.\n        '''\n        # Wait for a response\n        self._conn.sock.setblocking(True)\n        # Parse the response\n        response = self._bytes\n        while True:\n            try:\n                _bytes = self._conn.sock.recv(1)\n            except http_client.socket.error:\n                # For error 54: Connection reset by peer\n                # (and perhaps others)\n                return six.b('')\n            if _bytes == six.b(''):\n                break\n            else:\n                response += _bytes\n        # Set recv to be non-blocking again\n        self._conn.sock.setblocking(False)\n\n        # Convert the response string to a http_client.HTTPResponse\n        # object with a bit of a hack\n        if response != six.b(''):\n            # Taken from\n            # http://pythonwise.blogspot.ca/2010/02/parse-http-response.html\n            try:\n                response = http_client.HTTPResponse(_FakeSocket(response))\n                response.begin()\n            except:\n                # Bad headers ... etc.\n                response = six.b('')\n        return response\n\n    def _isconnected(self):\n        ''' Return True if the socket is still connected\n        to the server, False otherwise.\n\n        This check is done in 3 steps:\n        1 - Check if we have closed the connection\n        2 - Check if the original socket connection failed\n        3 - Check if the server has returned any data. If they have,\n            assume that the server closed the response after they sent\n            the data, i.e. that the data was the HTTP response.\n        '''\n\n        # 1 - check if we've closed the connection.\n        if self._closed:\n            return False\n\n        # 2 - Check if the original socket connection failed\n        # If this failed, then no socket was initialized\n        if self._conn.sock is None:\n            return False\n\n        try:\n            # 3 - Check if the server has returned any data.\n            # If they have, then start to store the response\n            # in _bytes.\n            self._bytes = six.b('')\n            self._bytes = self._conn.sock.recv(1)\n            return False\n        except http_client.socket.error as e:\n            # Check why recv failed\n            # Windows machines are the error codes\n            # that start with 1\n            # (http://msdn.microsoft.com/en-ca/library/windows/desktop/ms740668(v=vs.85).aspx)\n            if e.errno == 35 or e.errno == 10035:\n                # This is the \"Resource temporarily unavailable\" error\n                # which is thrown cuz there was nothing to receive, i.e.\n                # the server hasn't returned a response yet.\n                # This is a non-fatal error and the operation\n                # should be tried again.\n                # So, assume that the connection is still open.\n                return True\n            elif e.errno == 54 or e.errno == 10054:\n                # This is the \"Connection reset by peer\" error\n                # which is thrown cuz the server reset the\n                # socket, so the connection is closed.\n                return False\n            elif e.errno == 11:\n                # This is the \"Resource temporarily unavailable\" error\n                # which happens because the \"operation would have blocked\n                # but nonblocking operation was requested\".\n                # We require non-blocking reading of this socket because\n                # we don't want to wait around for a response, we just\n                # want to see if a response is currently available. So\n                # let's just assume that we're still connected and\n                # hopefully recieve some data on the next try.\n                return True\n            else:\n                # Unknown scenario\n                raise e\n\n    def _reconnect(self):\n        ''' Connect if disconnected.\n        Retry self.maxtries times with delays\n        '''\n        if not self._isconnected():\n            try:\n                self._connect()\n            except http_client.socket.error as e:\n                # Attempt to reconnect if the connection was refused\n                if e.errno == 61 or e.errno == 10061:\n                    # errno 61 is the \"Connection Refused\" error\n                    time.sleep(self._delay)\n                    self._delay += self._delay  # fibonacii delays\n                    self._tries += 1\n                    if self._tries < self.maxtries:\n                        self._reconnect()\n                    else:\n                        self._reset_retries()\n                        raise e\n                else:\n                    # Unknown scenario\n                    raise e\n\n        # Reconnect worked - reset _closed\n        self._closed = False\n\n    def _reset_retries(self):\n        ''' Reset the connect counters and delays\n        '''\n        self._tries = 0\n        self._delay = 1\n\n\nclass _FakeSocket(six.StringIO):\n    # Used to construct a http_client.HTTPResponse object\n    # from a string.\n    # Thx to: http://pythonwise.blogspot.ca/2010/02/parse-http-response.html\n    def makefile(self, *args, **kwargs):\n        return self\n", "path": "plotly/plotly/chunked_requests/chunked_request.py"}]}