We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
images.build failing on container build output
The ImageCollection.build() method parses the `docker build` output to extract the name of the image being built by looking for the string "Successfully built {sha256}".  Some commands in a Dockerfile can also produce this string causing the build() method to return early with an incorrect image name.

Example output from a `RUN pip install cffi` command:
```
 ...
Building wheels for collected packages: cffi, pycparser
  Running setup.py bdist_wheel for cffi
  Stored in directory: /root/.cache/pip/wheels/ea/df/5c/7d11cd4eec7b94be3b0ec4ed0076e0f38846a22c7200576149
  Running setup.py bdist_wheel for pycparser
  Stored in directory: /root/.cache/pip/wheels/bc/07/7e/cd81c0b23417ebaed9eb2584c00bd539871d5309a7a2324953
Successfully built cffi pycparser
...
```

A partial fix is to make the regex used to search for the string more restrictive by adding start and end anchors.  This can still result in some false positives.
A more complete fix only checks the last line of output for the "Success..." string.
PR in progress.

```
docker==2.3.0
docker-pycreds==0.2.1
Python 2.7.5
Client:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-common-1.12.6-16.el7.x86_64
 Go version:      go1.7.4
 Git commit:      3a094bd/1.12.6
 Built:           Tue Mar 21 13:30:59 2017
 OS/Arch:         linux/amd64

Server:
 Version:         17.03.1-ce
 API version:     1.27
 Package version: 
 Go version:      go1.7.5
 Git commit:      c6d412e
 Built:           Fri Mar 24 00:00:50 2017
 OS/Arch:         linux/amd64
```

--- 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             target (str): Name of the build-stage to build in a multi-stage
155                 Dockerfile.
156 
157         Returns:
158             (:py:class:`Image`): The built image.
159 
160         Raises:
161             :py:class:`docker.errors.BuildError`
162                 If there is an error during the build.
163             :py:class:`docker.errors.APIError`
164                 If the server returns any other error.
165             ``TypeError``
166                 If neither ``path`` nor ``fileobj`` is specified.
167         """
168         resp = self.client.api.build(**kwargs)
169         if isinstance(resp, six.string_types):
170             return self.get(resp)
171         last_event = None
172         for chunk in json_stream(resp):
173             if 'error' in chunk:
174                 raise BuildError(chunk['error'])
175             if 'stream' in chunk:
176                 match = re.search(
177                     r'(Successfully built |sha256:)([0-9a-f]+)',
178                     chunk['stream']
179                 )
180                 if match:
181                     image_id = match.group(2)
182                     return self.get(image_id)
183             last_event = chunk
184 
185         raise BuildError(last_event or 'Unknown')
186 
187     def get(self, name):
188         """
189         Gets an image.
190 
191         Args:
192             name (str): The name of the image.
193 
194         Returns:
195             (:py:class:`Image`): The image.
196 
197         Raises:
198             :py:class:`docker.errors.ImageNotFound`
199                 If the image does not exist.
200             :py:class:`docker.errors.APIError`
201                 If the server returns an error.
202         """
203         return self.prepare_model(self.client.api.inspect_image(name))
204 
205     def list(self, name=None, all=False, filters=None):
206         """
207         List images on the server.
208 
209         Args:
210             name (str): Only show images belonging to the repository ``name``
211             all (bool): Show intermediate image layers. By default, these are
212                 filtered out.
213             filters (dict): Filters to be processed on the image list.
214                 Available filters:
215                 - ``dangling`` (bool)
216                 - ``label`` (str): format either ``key`` or ``key=value``
217 
218         Returns:
219             (list of :py:class:`Image`): The images.
220 
221         Raises:
222             :py:class:`docker.errors.APIError`
223                 If the server returns an error.
224         """
225         resp = self.client.api.images(name=name, all=all, filters=filters)
226         return [self.prepare_model(r) for r in resp]
227 
228     def load(self, data):
229         """
230         Load an image that was previously saved using
231         :py:meth:`~docker.models.images.Image.save` (or ``docker save``).
232         Similar to ``docker load``.
233 
234         Args:
235             data (binary): Image data to be loaded.
236 
237         Raises:
238             :py:class:`docker.errors.APIError`
239                 If the server returns an error.
240         """
241         return self.client.api.load_image(data)
242 
243     def pull(self, name, tag=None, **kwargs):
244         """
245         Pull an image of the given name and return it. Similar to the
246         ``docker pull`` command.
247 
248         If you want to get the raw pull output, use the
249         :py:meth:`~docker.api.image.ImageApiMixin.pull` method in the
250         low-level API.
251 
252         Args:
253             repository (str): The repository to pull
254             tag (str): The tag to pull
255             insecure_registry (bool): Use an insecure registry
256             auth_config (dict): Override the credentials that
257                 :py:meth:`~docker.client.DockerClient.login` has set for
258                 this request. ``auth_config`` should contain the ``username``
259                 and ``password`` keys to be valid.
260 
261         Returns:
262             (:py:class:`Image`): The image that has been pulled.
263 
264         Raises:
265             :py:class:`docker.errors.APIError`
266                 If the server returns an error.
267 
268         Example:
269 
270             >>> image = client.images.pull('busybox')
271         """
272         self.client.api.pull(name, tag=tag, **kwargs)
273         return self.get('{0}:{1}'.format(name, tag) if tag else name)
274 
275     def push(self, repository, tag=None, **kwargs):
276         return self.client.api.push(repository, tag=tag, **kwargs)
277     push.__doc__ = APIClient.push.__doc__
278 
279     def remove(self, *args, **kwargs):
280         self.client.api.remove_image(*args, **kwargs)
281     remove.__doc__ = APIClient.remove_image.__doc__
282 
283     def search(self, *args, **kwargs):
284         return self.client.api.search(*args, **kwargs)
285     search.__doc__ = APIClient.search.__doc__
286 
287     def prune(self, filters=None):
288         return self.client.api.prune_images(filters=filters)
289     prune.__doc__ = APIClient.prune_images.__doc__
290
```
--- 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
@@ -169,19 +169,20 @@
         if isinstance(resp, six.string_types):
             return self.get(resp)
         last_event = None
+        image_id = None
         for chunk in json_stream(resp):
             if 'error' in chunk:
                 raise BuildError(chunk['error'])
             if 'stream' in chunk:
                 match = re.search(
-                    r'(Successfully built |sha256:)([0-9a-f]+)',
+                    r'(^Successfully built |sha256:)([0-9a-f]+)$',
                     chunk['stream']
                 )
                 if match:
                     image_id = match.group(2)
-                    return self.get(image_id)
             last_event = chunk
-
+        if image_id:
+            return self.get(image_id)
         raise BuildError(last_event or '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@@ -169,19 +169,20 @@\n         if isinstance(resp, six.string_types):\n             return self.get(resp)\n         last_event = None\n+        image_id = None\n         for chunk in json_stream(resp):\n             if 'error' in chunk:\n                 raise BuildError(chunk['error'])\n             if 'stream' in chunk:\n                 match = re.search(\n-                    r'(Successfully built |sha256:)([0-9a-f]+)',\n+                    r'(^Successfully built |sha256:)([0-9a-f]+)$',\n                     chunk['stream']\n                 )\n                 if match:\n                     image_id = match.group(2)\n-                    return self.get(image_id)\n             last_event = chunk\n-\n+        if image_id:\n+            return self.get(image_id)\n         raise BuildError(last_event or 'Unknown')\n \n     def get(self, name):\n", "issue": "images.build failing on container build output\nThe ImageCollection.build() method parses the `docker build` output to extract the name of the image being built by looking for the string \"Successfully built {sha256}\".  Some commands in a Dockerfile can also produce this string causing the build() method to return early with an incorrect image name.\r\n\r\nExample output from a `RUN pip install cffi` command:\r\n```\r\n ...\r\nBuilding wheels for collected packages: cffi, pycparser\r\n  Running setup.py bdist_wheel for cffi\r\n  Stored in directory: /root/.cache/pip/wheels/ea/df/5c/7d11cd4eec7b94be3b0ec4ed0076e0f38846a22c7200576149\r\n  Running setup.py bdist_wheel for pycparser\r\n  Stored in directory: /root/.cache/pip/wheels/bc/07/7e/cd81c0b23417ebaed9eb2584c00bd539871d5309a7a2324953\r\nSuccessfully built cffi pycparser\r\n...\r\n```\r\n\r\nA partial fix is to make the regex used to search for the string more restrictive by adding start and end anchors.  This can still result in some false positives.\r\nA more complete fix only checks the last line of output for the \"Success...\" string.\r\nPR in progress.\r\n\r\n```\r\ndocker==2.3.0\r\ndocker-pycreds==0.2.1\r\nPython 2.7.5\r\nClient:\r\n Version:         1.12.6\r\n API version:     1.24\r\n Package version: docker-common-1.12.6-16.el7.x86_64\r\n Go version:      go1.7.4\r\n Git commit:      3a094bd/1.12.6\r\n Built:           Tue Mar 21 13:30:59 2017\r\n OS/Arch:         linux/amd64\r\n\r\nServer:\r\n Version:         17.03.1-ce\r\n API version:     1.27\r\n Package version: \r\n Go version:      go1.7.5\r\n Git commit:      c6d412e\r\n Built:           Fri Mar 24 00:00:50 2017\r\n OS/Arch:         linux/amd64\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            target (str): Name of the build-stage to build in a multi-stage\n                Dockerfile.\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        last_event = None\n        for chunk in json_stream(resp):\n            if 'error' in chunk:\n                raise BuildError(chunk['error'])\n            if 'stream' in chunk:\n                match = re.search(\n                    r'(Successfully built |sha256:)([0-9a-f]+)',\n                    chunk['stream']\n                )\n                if match:\n                    image_id = match.group(2)\n                    return self.get(image_id)\n            last_event = chunk\n\n        raise BuildError(last_event or '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`\n                If the image does not 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, tag=None, **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, tag=tag, **kwargs)\n        return self.get('{0}:{1}'.format(name, tag) if tag else 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            target (str): Name of the build-stage to build in a multi-stage\n                Dockerfile.\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        last_event = None\n        image_id = None\n        for chunk in json_stream(resp):\n            if 'error' in chunk:\n                raise BuildError(chunk['error'])\n            if 'stream' in chunk:\n                match = re.search(\n                    r'(^Successfully built |sha256:)([0-9a-f]+)$',\n                    chunk['stream']\n                )\n                if match:\n                    image_id = match.group(2)\n            last_event = chunk\n        if image_id:\n            return self.get(image_id)\n        raise BuildError(last_event or '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`\n                If the image does not 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, tag=None, **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, tag=tag, **kwargs)\n        return self.get('{0}:{1}'.format(name, tag) if tag else 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"}]}