From 9a98e7fc8ccbd4f744bc60023251414ea785c6da Mon Sep 17 00:00:00 2001 From: Paul Tagliamonte Date: Tue, 5 Nov 2013 22:15:20 -0500 Subject: [PATCH] Add events endpoint to the Client This is a bit of a hack; I added a method (and did a slight refactor of the old one) to handle getting the raw socket from the requests request. If the attach_sockets method isn't public, I'd suggest removing it entirely for a slightly more general one. This also needs some attention paid to validating legnth, and properly parsing the returned data by using the length. Signed-off-by: Paul Tagliamonte --- docker/client.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/docker/client.py b/docker/client.py index 149bad95..842fd71d 100644 --- a/docker/client.py +++ b/docker/client.py @@ -142,6 +142,19 @@ class Client(requests.Session): kwargs['headers']['Content-Type'] = 'application/json' return self.post(url, json.dumps(data2), **kwargs) + def _socket_connection(self, url, method='post', *args, **kwargs): + try: + handler = { + "post": self.post, + "get": self.get + }[method.lower()] + except KeyError: + raise KeyError("No such method: `%s`" % (method)) + + res = handler(url, *args, **kwargs) + self._raise_for_status(res) + return res.raw._fp.fp._sock + def attach_socket(self, container, params=None): if params is None: params = { @@ -153,12 +166,23 @@ class Client(requests.Session): container = container.get('Id') u = self._url("/containers/{0}/attach".format(container)) - res = self.post(u, None, params=params, stream=True) - self._raise_for_status(res) - # hijack the underlying socket from requests, icky - # but for some reason requests.iter_contents and ilk - # eventually block - return res.raw._fp.fp._sock + return self._socket_connection( + u, None, method='post', params=params, stream=True) + + def events(self): + u = self._url("/events") + + socket = self._socket_connection(u, method='get', stream=True) + + while True: + chunk = socket.recv(4096) + if chunk: + # Messages come in the format of length, data, newline. + length, data = chunk.split("\n", 1) + # XXX: Verify data length. + yield json.loads(data) + else: + break def attach(self, container): socket = self.attach_socket(container)