Repository: docker/docker-py

Issue:
AttributeError: 'SocketIO' object has no attribute 'raw'
As raised in https://github.com/docker/compose/issues/5353 but I think it's actually a docker-py issue:
docker-composeup redis
Creating procensus_redis_1 ... 
Creating procensus_redis_1

ERROR: for procensus_redis_1  'SocketIO' object has no attribute 'raw'

ERROR: for redis  'SocketIO' object has no attribute 'raw'
```pytb
Traceback (most recent call last):
  File "/home/graingert/.virtualenvs/gitlab/bin/docker-compose", line 11, in <module>
    sys.exit(main())
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/cli/main.py", line 68, in main
    command()
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/cli/main.py", line 121, in perform_command
    handler(command, command_options)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/cli/main.py", line 952, in up
    start=not no_start
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/project.py", line 455, in up
    get_deps,
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/parallel.py", line 70, in parallel_execute
    raise error_to_reraise
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/parallel.py", line 168, in producer
    result = func(obj)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/project.py", line 441, in do
    start=start
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/service.py", line 471, in execute_convergence_plan
    scale, detached, start
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/service.py", line 396, in _execute_convergence_create
    "Creating",
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/parallel.py", line 70, in parallel_execute
    raise error_to_reraise
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/parallel.py", line 168, in producer
    result = func(obj)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/service.py", line 394, in <lambda>
    lambda n: create_and_start(self, n),
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/service.py", line 387, in create_and_start
    container.attach_log_stream()
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/container.py", line 177, in attach_log_stream
    self.log_stream = self.attach(stdout=True, stderr=True, stream=True)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/compose/container.py", line 254, in attach
    return self.client.attach(self.id, *args, **kwargs)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/docker/utils/decorators.py", line 19, in wrapped
    return f(self, resource_id, *args, **kwargs)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/docker/api/container.py", line 56, in attach
    response, stream, self._check_is_tty(container)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/docker/api/client.py", line 368, in _read_from_socket
    socket = self._get_raw_response_socket(response)
  File "/home/graingert/.virtualenvs/gitlab/lib/python3.6/site-packages/docker/api/client.py", line 276, in _get_raw_response_socket
    sock = response.raw._fp.fp.raw
AttributeError: 'SocketIO' object has no attribute 'raw'
```


Discussion:
If I put a debugger here, I can see that:

```python
(Pdb) response
<Response [101]>
(Pdb) response.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x7f66cb884be0>
(Pdb) response.raw._fp
<docker.transport.unixconn.UnixHTTPResponse object at 0x7f66cb884ba8>
(Pdb) response.raw._fp.fp
<socket.SocketIO object at 0x7f66cb884c88>
(Pdb) response.raw._fp.fp.raw
*** AttributeError: 'SocketIO' object has no attribute 'raw'
(Pdb) response.raw._fp.fp._sock
<socket.socket fd=9, family=AddressFamily.AF_UNIX, type=2049, proto=0, raddr=/var/run/docker.sock>
(Pdb) self.base_url
'http+docker://localunixsocket'
```
I suspect the bug was introduced here: https://github.com/docker/docker-py/commit/1359eb1100d602c5115c07175724002d30a042ee
Function at fault https://github.com/docker/docker-py/blob/f238fe5554cca48bb9bb366a07bd219c090e445b/docker/api/client.py#L271-L280
Thanks for the report. Can you specify:
- what version of Python you're working with
- which OS you're running on
- which method you use to connect to the engine (Unix socket, https, named pipe?)

Thank you
I'm using python 3.6 connecting via 'http+docker://localunixsocket' on Ubuntu 17.10

Thanks! Python 3.6 is recurrent in the other reports as well. I'll look into it asap.
Same error message but on Python **3.4**, Ubuntu 14.04, http+docker://localunixsocket here.

ERROR: for <xxx>  'SocketIO' object has no attribute 'raw'
Traceback (most recent call last):
  File "/usr/local/bin/docker-compose", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.4/dist-packages/compose/cli/main.py", line 68, in main
I've also seen this with python 3.4 on Ubuntu 14.04, connected...however calls to 'exec_run' connect.

Came up in an automated build on travis.

File "myscript.py", line 209, in my_function
    container.exec_run(['/load_data.bash', 'thing'])
  File "/home/travis/.local/lib/python3.4/site-packages/docker/models/containers.py", line 165, in exec_run
    resp['Id'], detach=detach, tty=tty, stream=stream, socket=socket
  File "/home/travis/.local/lib/python3.4/site-packages/docker/utils/decorators.py", line 34, in wrapper
    return f(self, *args, **kwargs)
  File "/home/travis/.local/lib/python3.4/site-packages/docker/utils/decorators.py", line 19, in wrapped
    return f(self, resource_id, *args, **kwargs)
  File "/home/travis/.local/lib/python3.4/site-packages/docker/api/exec_api.py", line 159, in exec_start
    return self._read_from_socket(res, stream, tty)
  File "/home/travis/.local/lib/python3.4/site-packages/docker/api/client.py", line 368, in _read_from_socket
    socket = self._get_raw_response_socket(response)
  File "/home/travis/.local/lib/python3.4/site-packages/docker/api/client.py", line 276, in _get_raw_response_socket
    sock = response.raw._fp.fp.raw
AttributeError: 'SocketIO' object has no attribute 'raw'

Resolving patch:
diff --git a/docker/transport/unixconn.py b/docker/transport/unixconn.py
--- a/docker/transport/unixconn.py
+++ b/docker/transport/unixconn.py
@@ -21,13 +21,12 @@
 class UnixHTTPResponse(httplib.HTTPResponse, object):
     def __init__(self, sock, *args, **kwargs):
         disable_buffering = kwargs.pop('disable_buffering', False)
+        if six.PY2:
+            # FIXME: We may need to disable buffering on Py3 as well,
+            # but there's no clear way to do it at the moment. See:
+            # https://github.com/docker/docker-py/issues/1799
+            kwargs['buffering'] = not disable_buffering
         super(UnixHTTPResponse, self).__init__(sock, *args, **kwargs)
-        if disable_buffering is True:
-            # We must first create a new pointer then close the old one
-            # to avoid closing the underlying socket.
-            new_fp = sock.makefile('rb', 0)
-            self.fp.close()
-            self.fp = new_fp
 
 
 class UnixHTTPConnection(httplib.HTTPConnection, object):


Test patch: