We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
images.build fails when using tag argument.
When using the `tag` kwarg on `client.images.build`, it will always throw a Build Error.

The api.build output looks like this

```
['{"stream":"Step 1/4 : FROM scratch\\n"}\r\n',
 '{"stream":" ---\\u003e \\n"}\r\n',
 '{"stream":"Step 2/4 : LABEL com.nvidia.volumes.needed \\"nvidia_driver\\"\\n"}\r\n',
 '{"stream":" ---\\u003e Using cache\\n"}\r\n',
 '{"stream":" ---\\u003e 36ec3942c5f5\\n"}\r\n',
 '{"stream":"Step 3/4 : SHELL /usr/local/nvidia/bin/nvidia-smi\\n"}\r\n',
 '{"stream":" ---\\u003e Running in f875d54529eb\\n"}\r\n',
 '{"stream":" ---\\u003e b750cf87aed6\\n"}\r\n',
 '{"stream":"Step 4/4 : CMD -L\\n"}\r\n',
 '{"stream":" ---\\u003e Running in f3f9e21b8171\\n"}\r\n',
 '{"stream":" ---\\u003e 61c46a80da73\\n"}\r\n',
 '{"stream":"Successfully built 61c46a80da73\\n"}\r\n',
 '{"stream":"Successfully tagged 5b3bc129-d296-4b7d-872c-bc7117d4f327:latest\\n"}\r\n']
```

The problem can be tracked down to [here](https://github.com/docker/docker-py/blob/2.2.1-release/docker/models/images.py#L164-L167). The code is assuming the "Successfully built" comes last, however in the tag case, this is not true.

Two ideas are to either 

1. Search the last two lines
2. Or in case that is not enough, search all the lines for "Successfully built"


I'm using docker server 17.05.0-ce-rc1


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `docker/models/images.py`
Content:
```
1 import re
2 
3 import six
4 
5 from ..api import APIClient
6 from ..errors import BuildError
7 from ..utils.json_stream import json_stream
8 from .resource import Collection, Model
9 
10 
11 class Image(Model):
12     """
13     An image on the server.
14     """
15     def __repr__(self):
16         return "<%s: '%s'>" % (self.__class__.__name__, "', '".join(self.tags))
17 
18     @property
19     def labels(self):
20         """
21         The labels of an image as dictionary.
22         """
23         result = self.attrs['Config'].get('Labels')
24         return result or {}
25 
26     @property
27     def short_id(self):
28         """
29         The ID of the image truncated to 10 characters, plus the ``sha256:``
30         prefix.
31         """
32         if self.id.startswith('sha256:'):
33             return self.id[:17]
34         return self.id[:10]
35 
36     @property
37     def tags(self):
38         """
39         The image's tags.
40         """
41         tags = self.attrs.get('RepoTags')
42         if tags is None:
43             tags = []
44         return [tag for tag in tags if tag != '<none>:<none>']
45 
46     def history(self):
47         """
48         Show the history of an image.
49 
50         Returns:
51             (str): The history of the image.
52 
53         Raises:
54             :py:class:`docker.errors.APIError`
55                 If the server returns an error.
56         """
57         return self.client.api.history(self.id)
58 
59     def save(self):
60         """
61         Get a tarball of an image. Similar to the ``docker save`` command.
62 
63         Returns:
64             (urllib3.response.HTTPResponse object): The response from the
65             daemon.
66 
67         Raises:
68             :py:class:`docker.errors.APIError`
69                 If the server returns an error.
70 
71         Example:
72 
73             >>> image = cli.images.get("fedora:latest")
74             >>> resp = image.save()
75             >>> f = open('/tmp/fedora-latest.tar', 'w')
76             >>> for chunk in resp.stream():
77             >>>     f.write(chunk)
78             >>> f.close()
79         """
80         return self.client.api.get_image(self.id)
81 
82     def tag(self, repository, tag=None, **kwargs):
83         """
84         Tag this image into a repository. Similar to the ``docker tag``
85         command.
86 
87         Args:
88             repository (str): The repository to set for the tag
89             tag (str): The tag name
90             force (bool): Force
91 
92         Raises:
93             :py:class:`docker.errors.APIError`
94                 If the server returns an error.
95 
96         Returns:
97             (bool): ``True`` if successful
98         """
99         self.client.api.tag(self.id, repository, tag=tag, **kwargs)
100 
101 
102 class ImageCollection(Collection):
103     model = Image
104 
105     def build(self, **kwargs):
106         """
107         Build an image and return it. Similar to the ``docker build``
108         command. Either ``path`` or ``fileobj`` must be set.
109 
110         If you have a tar file for the Docker build context (including a
111         Dockerfile) already, pass a readable file-like object to ``fileobj``
112         and also pass ``custom_context=True``. If the stream is compressed
113         also, set ``encoding`` to the correct value (e.g ``gzip``).
114 
115         If you want to get the raw output of the build, use the
116         :py:meth:`~docker.api.build.BuildApiMixin.build` method in the
117         low-level API.
118 
119         Args:
120             path (str): Path to the directory containing the Dockerfile
121             fileobj: A file object to use as the Dockerfile. (Or a file-like
122                 object)
123             tag (str): A tag to add to the final image
124             quiet (bool): Whether to return the status
125             nocache (bool): Don't use the cache when set to ``True``
126             rm (bool): Remove intermediate containers. The ``docker build``
127                 command now defaults to ``--rm=true``, but we have kept the old
128                 default of `False` to preserve backward compatibility
129             stream (bool): *Deprecated for API version > 1.8 (always True)*.
130                 Return a blocking generator you can iterate over to retrieve
131                 build output as it happens
132             timeout (int): HTTP timeout
133             custom_context (bool): Optional if using ``fileobj``
134             encoding (str): The encoding for a stream. Set to ``gzip`` for
135                 compressing
136             pull (bool): Downloads any updates to the FROM image in Dockerfiles
137             forcerm (bool): Always remove intermediate containers, even after
138                 unsuccessful builds
139             dockerfile (str): path within the build context to the Dockerfile
140             buildargs (dict): A dictionary of build arguments
141             container_limits (dict): A dictionary of limits applied to each
142                 container created by the build process. Valid keys:
143 
144                 - memory (int): set memory limit for build
145                 - memswap (int): Total memory (memory + swap), -1 to disable
146                     swap
147                 - cpushares (int): CPU shares (relative weight)
148                 - cpusetcpus (str): CPUs in which to allow execution, e.g.,
149                     ``"0-3"``, ``"0,1"``
150             decode (bool): If set to ``True``, the returned stream will be
151                 decoded into dicts on the fly. Default ``False``.
152             cache_from (list): A list of images used for build cache
153                 resolution.
154 
155         Returns:
156             (:py:class:`Image`): The built image.
157 
158         Raises:
159             :py:class:`docker.errors.BuildError`
160                 If there is an error during the build.
161             :py:class:`docker.errors.APIError`
162                 If the server returns any other error.
163             ``TypeError``
164                 If neither ``path`` nor ``fileobj`` is specified.
165         """
166         resp = self.client.api.build(**kwargs)
167         if isinstance(resp, six.string_types):
168             return self.get(resp)
169         events = list(json_stream(resp))
170         if not events:
171             return BuildError('Unknown')
172         event = events[-1]
173         if 'stream' in event:
174             match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',
175                               event.get('stream', ''))
176             if match:
177                 image_id = match.group(2)
178                 return self.get(image_id)
179 
180         raise BuildError(event.get('error') or event)
181 
182     def get(self, name):
183         """
184         Gets an image.
185 
186         Args:
187             name (str): The name of the image.
188 
189         Returns:
190             (:py:class:`Image`): The image.
191 
192         Raises:
193             :py:class:`docker.errors.ImageNotFound` If the image does not
194             exist.
195             :py:class:`docker.errors.APIError`
196                 If the server returns an error.
197         """
198         return self.prepare_model(self.client.api.inspect_image(name))
199 
200     def list(self, name=None, all=False, filters=None):
201         """
202         List images on the server.
203 
204         Args:
205             name (str): Only show images belonging to the repository ``name``
206             all (bool): Show intermediate image layers. By default, these are
207                 filtered out.
208             filters (dict): Filters to be processed on the image list.
209                 Available filters:
210                 - ``dangling`` (bool)
211                 - ``label`` (str): format either ``key`` or ``key=value``
212 
213         Returns:
214             (list of :py:class:`Image`): The images.
215 
216         Raises:
217             :py:class:`docker.errors.APIError`
218                 If the server returns an error.
219         """
220         resp = self.client.api.images(name=name, all=all, filters=filters)
221         return [self.prepare_model(r) for r in resp]
222 
223     def load(self, data):
224         """
225         Load an image that was previously saved using
226         :py:meth:`~docker.models.images.Image.save` (or ``docker save``).
227         Similar to ``docker load``.
228 
229         Args:
230             data (binary): Image data to be loaded.
231 
232         Raises:
233             :py:class:`docker.errors.APIError`
234                 If the server returns an error.
235         """
236         return self.client.api.load_image(data)
237 
238     def pull(self, name, **kwargs):
239         """
240         Pull an image of the given name and return it. Similar to the
241         ``docker pull`` command.
242 
243         If you want to get the raw pull output, use the
244         :py:meth:`~docker.api.image.ImageApiMixin.pull` method in the
245         low-level API.
246 
247         Args:
248             repository (str): The repository to pull
249             tag (str): The tag to pull
250             insecure_registry (bool): Use an insecure registry
251             auth_config (dict): Override the credentials that
252                 :py:meth:`~docker.client.DockerClient.login` has set for
253                 this request. ``auth_config`` should contain the ``username``
254                 and ``password`` keys to be valid.
255 
256         Returns:
257             (:py:class:`Image`): The image that has been pulled.
258 
259         Raises:
260             :py:class:`docker.errors.APIError`
261                 If the server returns an error.
262 
263         Example:
264 
265             >>> image = client.images.pull('busybox')
266         """
267         self.client.api.pull(name, **kwargs)
268         return self.get(name)
269 
270     def push(self, repository, tag=None, **kwargs):
271         return self.client.api.push(repository, tag=tag, **kwargs)
272     push.__doc__ = APIClient.push.__doc__
273 
274     def remove(self, *args, **kwargs):
275         self.client.api.remove_image(*args, **kwargs)
276     remove.__doc__ = APIClient.remove_image.__doc__
277 
278     def search(self, *args, **kwargs):
279         return self.client.api.search(*args, **kwargs)
280     search.__doc__ = APIClient.search.__doc__
281 
282     def prune(self, filters=None):
283         return self.client.api.prune_images(filters=filters)
284     prune.__doc__ = APIClient.prune_images.__doc__
285
```
--- 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/docker/models/images.py b/docker/models/images.py
--- a/docker/models/images.py
+++ b/docker/models/images.py
@@ -166,18 +166,18 @@
         resp = self.client.api.build(**kwargs)
         if isinstance(resp, six.string_types):
             return self.get(resp)
-        events = list(json_stream(resp))
-        if not events:
-            return BuildError('Unknown')
-        event = events[-1]
-        if 'stream' in event:
-            match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',
-                              event.get('stream', ''))
-            if match:
-                image_id = match.group(2)
-                return self.get(image_id)
-
-        raise BuildError(event.get('error') or event)
+        for chunk in json_stream(resp):
+            if 'error' in chunk:
+                raise BuildError(chunk['error'])
+                break
+            if 'stream' in chunk:
+                match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',
+                                  chunk['stream'])
+                if match:
+                    image_id = match.group(2)
+                    return self.get(image_id)
+
+        return BuildError('Unknown')
 
     def get(self, name):
         """

{"golden_diff": "diff --git a/docker/models/images.py b/docker/models/images.py\n--- a/docker/models/images.py\n+++ b/docker/models/images.py\n@@ -166,18 +166,18 @@\n         resp = self.client.api.build(**kwargs)\n         if isinstance(resp, six.string_types):\n             return self.get(resp)\n-        events = list(json_stream(resp))\n-        if not events:\n-            return BuildError('Unknown')\n-        event = events[-1]\n-        if 'stream' in event:\n-            match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',\n-                              event.get('stream', ''))\n-            if match:\n-                image_id = match.group(2)\n-                return self.get(image_id)\n-\n-        raise BuildError(event.get('error') or event)\n+        for chunk in json_stream(resp):\n+            if 'error' in chunk:\n+                raise BuildError(chunk['error'])\n+                break\n+            if 'stream' in chunk:\n+                match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',\n+                                  chunk['stream'])\n+                if match:\n+                    image_id = match.group(2)\n+                    return self.get(image_id)\n+\n+        return BuildError('Unknown')\n \n     def get(self, name):\n         \"\"\"\n", "issue": "images.build fails when using tag argument.\nWhen using the `tag` kwarg on `client.images.build`, it will always throw a Build Error.\r\n\r\nThe api.build output looks like this\r\n\r\n```\r\n['{\"stream\":\"Step 1/4 : FROM scratch\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e \\\\n\"}\\r\\n',\r\n '{\"stream\":\"Step 2/4 : LABEL com.nvidia.volumes.needed \\\\\"nvidia_driver\\\\\"\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e Using cache\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e 36ec3942c5f5\\\\n\"}\\r\\n',\r\n '{\"stream\":\"Step 3/4 : SHELL /usr/local/nvidia/bin/nvidia-smi\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e Running in f875d54529eb\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e b750cf87aed6\\\\n\"}\\r\\n',\r\n '{\"stream\":\"Step 4/4 : CMD -L\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e Running in f3f9e21b8171\\\\n\"}\\r\\n',\r\n '{\"stream\":\" ---\\\\u003e 61c46a80da73\\\\n\"}\\r\\n',\r\n '{\"stream\":\"Successfully built 61c46a80da73\\\\n\"}\\r\\n',\r\n '{\"stream\":\"Successfully tagged 5b3bc129-d296-4b7d-872c-bc7117d4f327:latest\\\\n\"}\\r\\n']\r\n```\r\n\r\nThe problem can be tracked down to [here](https://github.com/docker/docker-py/blob/2.2.1-release/docker/models/images.py#L164-L167). The code is assuming the \"Successfully built\" comes last, however in the tag case, this is not true.\r\n\r\nTwo ideas are to either \r\n\r\n1. Search the last two lines\r\n2. Or in case that is not enough, search all the lines for \"Successfully built\"\r\n\r\n\r\nI'm using docker server 17.05.0-ce-rc1\r\n\n", "before_files": [{"content": "import re\n\nimport six\n\nfrom ..api import APIClient\nfrom ..errors import BuildError\nfrom ..utils.json_stream import json_stream\nfrom .resource import Collection, Model\n\n\nclass Image(Model):\n    \"\"\"\n    An image on the server.\n    \"\"\"\n    def __repr__(self):\n        return \"<%s: '%s'>\" % (self.__class__.__name__, \"', '\".join(self.tags))\n\n    @property\n    def labels(self):\n        \"\"\"\n        The labels of an image as dictionary.\n        \"\"\"\n        result = self.attrs['Config'].get('Labels')\n        return result or {}\n\n    @property\n    def short_id(self):\n        \"\"\"\n        The ID of the image truncated to 10 characters, plus the ``sha256:``\n        prefix.\n        \"\"\"\n        if self.id.startswith('sha256:'):\n            return self.id[:17]\n        return self.id[:10]\n\n    @property\n    def tags(self):\n        \"\"\"\n        The image's tags.\n        \"\"\"\n        tags = self.attrs.get('RepoTags')\n        if tags is None:\n            tags = []\n        return [tag for tag in tags if tag != '<none>:<none>']\n\n    def history(self):\n        \"\"\"\n        Show the history of an image.\n\n        Returns:\n            (str): The history of the image.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.client.api.history(self.id)\n\n    def save(self):\n        \"\"\"\n        Get a tarball of an image. Similar to the ``docker save`` command.\n\n        Returns:\n            (urllib3.response.HTTPResponse object): The response from the\n            daemon.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n\n        Example:\n\n            >>> image = cli.images.get(\"fedora:latest\")\n            >>> resp = image.save()\n            >>> f = open('/tmp/fedora-latest.tar', 'w')\n            >>> for chunk in resp.stream():\n            >>>     f.write(chunk)\n            >>> f.close()\n        \"\"\"\n        return self.client.api.get_image(self.id)\n\n    def tag(self, repository, tag=None, **kwargs):\n        \"\"\"\n        Tag this image into a repository. Similar to the ``docker tag``\n        command.\n\n        Args:\n            repository (str): The repository to set for the tag\n            tag (str): The tag name\n            force (bool): Force\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n\n        Returns:\n            (bool): ``True`` if successful\n        \"\"\"\n        self.client.api.tag(self.id, repository, tag=tag, **kwargs)\n\n\nclass ImageCollection(Collection):\n    model = Image\n\n    def build(self, **kwargs):\n        \"\"\"\n        Build an image and return it. Similar to the ``docker build``\n        command. Either ``path`` or ``fileobj`` must be set.\n\n        If you have a tar file for the Docker build context (including a\n        Dockerfile) already, pass a readable file-like object to ``fileobj``\n        and also pass ``custom_context=True``. If the stream is compressed\n        also, set ``encoding`` to the correct value (e.g ``gzip``).\n\n        If you want to get the raw output of the build, use the\n        :py:meth:`~docker.api.build.BuildApiMixin.build` method in the\n        low-level API.\n\n        Args:\n            path (str): Path to the directory containing the Dockerfile\n            fileobj: A file object to use as the Dockerfile. (Or a file-like\n                object)\n            tag (str): A tag to add to the final image\n            quiet (bool): Whether to return the status\n            nocache (bool): Don't use the cache when set to ``True``\n            rm (bool): Remove intermediate containers. The ``docker build``\n                command now defaults to ``--rm=true``, but we have kept the old\n                default of `False` to preserve backward compatibility\n            stream (bool): *Deprecated for API version > 1.8 (always True)*.\n                Return a blocking generator you can iterate over to retrieve\n                build output as it happens\n            timeout (int): HTTP timeout\n            custom_context (bool): Optional if using ``fileobj``\n            encoding (str): The encoding for a stream. Set to ``gzip`` for\n                compressing\n            pull (bool): Downloads any updates to the FROM image in Dockerfiles\n            forcerm (bool): Always remove intermediate containers, even after\n                unsuccessful builds\n            dockerfile (str): path within the build context to the Dockerfile\n            buildargs (dict): A dictionary of build arguments\n            container_limits (dict): A dictionary of limits applied to each\n                container created by the build process. Valid keys:\n\n                - memory (int): set memory limit for build\n                - memswap (int): Total memory (memory + swap), -1 to disable\n                    swap\n                - cpushares (int): CPU shares (relative weight)\n                - cpusetcpus (str): CPUs in which to allow execution, e.g.,\n                    ``\"0-3\"``, ``\"0,1\"``\n            decode (bool): If set to ``True``, the returned stream will be\n                decoded into dicts on the fly. Default ``False``.\n            cache_from (list): A list of images used for build cache\n                resolution.\n\n        Returns:\n            (:py:class:`Image`): The built image.\n\n        Raises:\n            :py:class:`docker.errors.BuildError`\n                If there is an error during the build.\n            :py:class:`docker.errors.APIError`\n                If the server returns any other error.\n            ``TypeError``\n                If neither ``path`` nor ``fileobj`` is specified.\n        \"\"\"\n        resp = self.client.api.build(**kwargs)\n        if isinstance(resp, six.string_types):\n            return self.get(resp)\n        events = list(json_stream(resp))\n        if not events:\n            return BuildError('Unknown')\n        event = events[-1]\n        if 'stream' in event:\n            match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',\n                              event.get('stream', ''))\n            if match:\n                image_id = match.group(2)\n                return self.get(image_id)\n\n        raise BuildError(event.get('error') or event)\n\n    def get(self, name):\n        \"\"\"\n        Gets an image.\n\n        Args:\n            name (str): The name of the image.\n\n        Returns:\n            (:py:class:`Image`): The image.\n\n        Raises:\n            :py:class:`docker.errors.ImageNotFound` If the image does not\n            exist.\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.prepare_model(self.client.api.inspect_image(name))\n\n    def list(self, name=None, all=False, filters=None):\n        \"\"\"\n        List images on the server.\n\n        Args:\n            name (str): Only show images belonging to the repository ``name``\n            all (bool): Show intermediate image layers. By default, these are\n                filtered out.\n            filters (dict): Filters to be processed on the image list.\n                Available filters:\n                - ``dangling`` (bool)\n                - ``label`` (str): format either ``key`` or ``key=value``\n\n        Returns:\n            (list of :py:class:`Image`): The images.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        resp = self.client.api.images(name=name, all=all, filters=filters)\n        return [self.prepare_model(r) for r in resp]\n\n    def load(self, data):\n        \"\"\"\n        Load an image that was previously saved using\n        :py:meth:`~docker.models.images.Image.save` (or ``docker save``).\n        Similar to ``docker load``.\n\n        Args:\n            data (binary): Image data to be loaded.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.client.api.load_image(data)\n\n    def pull(self, name, **kwargs):\n        \"\"\"\n        Pull an image of the given name and return it. Similar to the\n        ``docker pull`` command.\n\n        If you want to get the raw pull output, use the\n        :py:meth:`~docker.api.image.ImageApiMixin.pull` method in the\n        low-level API.\n\n        Args:\n            repository (str): The repository to pull\n            tag (str): The tag to pull\n            insecure_registry (bool): Use an insecure registry\n            auth_config (dict): Override the credentials that\n                :py:meth:`~docker.client.DockerClient.login` has set for\n                this request. ``auth_config`` should contain the ``username``\n                and ``password`` keys to be valid.\n\n        Returns:\n            (:py:class:`Image`): The image that has been pulled.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n\n        Example:\n\n            >>> image = client.images.pull('busybox')\n        \"\"\"\n        self.client.api.pull(name, **kwargs)\n        return self.get(name)\n\n    def push(self, repository, tag=None, **kwargs):\n        return self.client.api.push(repository, tag=tag, **kwargs)\n    push.__doc__ = APIClient.push.__doc__\n\n    def remove(self, *args, **kwargs):\n        self.client.api.remove_image(*args, **kwargs)\n    remove.__doc__ = APIClient.remove_image.__doc__\n\n    def search(self, *args, **kwargs):\n        return self.client.api.search(*args, **kwargs)\n    search.__doc__ = APIClient.search.__doc__\n\n    def prune(self, filters=None):\n        return self.client.api.prune_images(filters=filters)\n    prune.__doc__ = APIClient.prune_images.__doc__\n", "path": "docker/models/images.py"}], "after_files": [{"content": "import re\n\nimport six\n\nfrom ..api import APIClient\nfrom ..errors import BuildError\nfrom ..utils.json_stream import json_stream\nfrom .resource import Collection, Model\n\n\nclass Image(Model):\n    \"\"\"\n    An image on the server.\n    \"\"\"\n    def __repr__(self):\n        return \"<%s: '%s'>\" % (self.__class__.__name__, \"', '\".join(self.tags))\n\n    @property\n    def labels(self):\n        \"\"\"\n        The labels of an image as dictionary.\n        \"\"\"\n        result = self.attrs['Config'].get('Labels')\n        return result or {}\n\n    @property\n    def short_id(self):\n        \"\"\"\n        The ID of the image truncated to 10 characters, plus the ``sha256:``\n        prefix.\n        \"\"\"\n        if self.id.startswith('sha256:'):\n            return self.id[:17]\n        return self.id[:10]\n\n    @property\n    def tags(self):\n        \"\"\"\n        The image's tags.\n        \"\"\"\n        tags = self.attrs.get('RepoTags')\n        if tags is None:\n            tags = []\n        return [tag for tag in tags if tag != '<none>:<none>']\n\n    def history(self):\n        \"\"\"\n        Show the history of an image.\n\n        Returns:\n            (str): The history of the image.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.client.api.history(self.id)\n\n    def save(self):\n        \"\"\"\n        Get a tarball of an image. Similar to the ``docker save`` command.\n\n        Returns:\n            (urllib3.response.HTTPResponse object): The response from the\n            daemon.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n\n        Example:\n\n            >>> image = cli.images.get(\"fedora:latest\")\n            >>> resp = image.save()\n            >>> f = open('/tmp/fedora-latest.tar', 'w')\n            >>> for chunk in resp.stream():\n            >>>     f.write(chunk)\n            >>> f.close()\n        \"\"\"\n        return self.client.api.get_image(self.id)\n\n    def tag(self, repository, tag=None, **kwargs):\n        \"\"\"\n        Tag this image into a repository. Similar to the ``docker tag``\n        command.\n\n        Args:\n            repository (str): The repository to set for the tag\n            tag (str): The tag name\n            force (bool): Force\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n\n        Returns:\n            (bool): ``True`` if successful\n        \"\"\"\n        self.client.api.tag(self.id, repository, tag=tag, **kwargs)\n\n\nclass ImageCollection(Collection):\n    model = Image\n\n    def build(self, **kwargs):\n        \"\"\"\n        Build an image and return it. Similar to the ``docker build``\n        command. Either ``path`` or ``fileobj`` must be set.\n\n        If you have a tar file for the Docker build context (including a\n        Dockerfile) already, pass a readable file-like object to ``fileobj``\n        and also pass ``custom_context=True``. If the stream is compressed\n        also, set ``encoding`` to the correct value (e.g ``gzip``).\n\n        If you want to get the raw output of the build, use the\n        :py:meth:`~docker.api.build.BuildApiMixin.build` method in the\n        low-level API.\n\n        Args:\n            path (str): Path to the directory containing the Dockerfile\n            fileobj: A file object to use as the Dockerfile. (Or a file-like\n                object)\n            tag (str): A tag to add to the final image\n            quiet (bool): Whether to return the status\n            nocache (bool): Don't use the cache when set to ``True``\n            rm (bool): Remove intermediate containers. The ``docker build``\n                command now defaults to ``--rm=true``, but we have kept the old\n                default of `False` to preserve backward compatibility\n            stream (bool): *Deprecated for API version > 1.8 (always True)*.\n                Return a blocking generator you can iterate over to retrieve\n                build output as it happens\n            timeout (int): HTTP timeout\n            custom_context (bool): Optional if using ``fileobj``\n            encoding (str): The encoding for a stream. Set to ``gzip`` for\n                compressing\n            pull (bool): Downloads any updates to the FROM image in Dockerfiles\n            forcerm (bool): Always remove intermediate containers, even after\n                unsuccessful builds\n            dockerfile (str): path within the build context to the Dockerfile\n            buildargs (dict): A dictionary of build arguments\n            container_limits (dict): A dictionary of limits applied to each\n                container created by the build process. Valid keys:\n\n                - memory (int): set memory limit for build\n                - memswap (int): Total memory (memory + swap), -1 to disable\n                    swap\n                - cpushares (int): CPU shares (relative weight)\n                - cpusetcpus (str): CPUs in which to allow execution, e.g.,\n                    ``\"0-3\"``, ``\"0,1\"``\n            decode (bool): If set to ``True``, the returned stream will be\n                decoded into dicts on the fly. Default ``False``.\n            cache_from (list): A list of images used for build cache\n                resolution.\n\n        Returns:\n            (:py:class:`Image`): The built image.\n\n        Raises:\n            :py:class:`docker.errors.BuildError`\n                If there is an error during the build.\n            :py:class:`docker.errors.APIError`\n                If the server returns any other error.\n            ``TypeError``\n                If neither ``path`` nor ``fileobj`` is specified.\n        \"\"\"\n        resp = self.client.api.build(**kwargs)\n        if isinstance(resp, six.string_types):\n            return self.get(resp)\n        for chunk in json_stream(resp):\n            if 'error' in chunk:\n                raise BuildError(chunk['error'])\n                break\n            if 'stream' in chunk:\n                match = re.search(r'(Successfully built |sha256:)([0-9a-f]+)',\n                                  chunk['stream'])\n                if match:\n                    image_id = match.group(2)\n                    return self.get(image_id)\n\n        return BuildError('Unknown')\n\n    def get(self, name):\n        \"\"\"\n        Gets an image.\n\n        Args:\n            name (str): The name of the image.\n\n        Returns:\n            (:py:class:`Image`): The image.\n\n        Raises:\n            :py:class:`docker.errors.ImageNotFound` If the image does not\n            exist.\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.prepare_model(self.client.api.inspect_image(name))\n\n    def list(self, name=None, all=False, filters=None):\n        \"\"\"\n        List images on the server.\n\n        Args:\n            name (str): Only show images belonging to the repository ``name``\n            all (bool): Show intermediate image layers. By default, these are\n                filtered out.\n            filters (dict): Filters to be processed on the image list.\n                Available filters:\n                - ``dangling`` (bool)\n                - ``label`` (str): format either ``key`` or ``key=value``\n\n        Returns:\n            (list of :py:class:`Image`): The images.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        resp = self.client.api.images(name=name, all=all, filters=filters)\n        return [self.prepare_model(r) for r in resp]\n\n    def load(self, data):\n        \"\"\"\n        Load an image that was previously saved using\n        :py:meth:`~docker.models.images.Image.save` (or ``docker save``).\n        Similar to ``docker load``.\n\n        Args:\n            data (binary): Image data to be loaded.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n        \"\"\"\n        return self.client.api.load_image(data)\n\n    def pull(self, name, **kwargs):\n        \"\"\"\n        Pull an image of the given name and return it. Similar to the\n        ``docker pull`` command.\n\n        If you want to get the raw pull output, use the\n        :py:meth:`~docker.api.image.ImageApiMixin.pull` method in the\n        low-level API.\n\n        Args:\n            repository (str): The repository to pull\n            tag (str): The tag to pull\n            insecure_registry (bool): Use an insecure registry\n            auth_config (dict): Override the credentials that\n                :py:meth:`~docker.client.DockerClient.login` has set for\n                this request. ``auth_config`` should contain the ``username``\n                and ``password`` keys to be valid.\n\n        Returns:\n            (:py:class:`Image`): The image that has been pulled.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n\n        Example:\n\n            >>> image = client.images.pull('busybox')\n        \"\"\"\n        self.client.api.pull(name, **kwargs)\n        return self.get(name)\n\n    def push(self, repository, tag=None, **kwargs):\n        return self.client.api.push(repository, tag=tag, **kwargs)\n    push.__doc__ = APIClient.push.__doc__\n\n    def remove(self, *args, **kwargs):\n        self.client.api.remove_image(*args, **kwargs)\n    remove.__doc__ = APIClient.remove_image.__doc__\n\n    def search(self, *args, **kwargs):\n        return self.client.api.search(*args, **kwargs)\n    search.__doc__ = APIClient.search.__doc__\n\n    def prune(self, filters=None):\n        return self.client.api.prune_images(filters=filters)\n    prune.__doc__ = APIClient.prune_images.__doc__\n", "path": "docker/models/images.py"}]}