We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
.dockerignore file with space-only lines breaks build on Windows
Originally reported in https://github.com/docker/compose/issues/5526

--- 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/api/build.py`
Content:
```
1 import json
2 import logging
3 import os
4 import re
5 
6 from .. import auth
7 from .. import constants
8 from .. import errors
9 from .. import utils
10 
11 
12 log = logging.getLogger(__name__)
13 
14 
15 class BuildApiMixin(object):
16     def build(self, path=None, tag=None, quiet=False, fileobj=None,
17               nocache=False, rm=False, stream=False, timeout=None,
18               custom_context=False, encoding=None, pull=False,
19               forcerm=False, dockerfile=None, container_limits=None,
20               decode=False, buildargs=None, gzip=False, shmsize=None,
21               labels=None, cache_from=None, target=None, network_mode=None,
22               squash=None, extra_hosts=None):
23         """
24         Similar to the ``docker build`` command. Either ``path`` or ``fileobj``
25         needs to be set. ``path`` can be a local path (to a directory
26         containing a Dockerfile) or a remote URL. ``fileobj`` must be a
27         readable file-like object to a Dockerfile.
28 
29         If you have a tar file for the Docker build context (including a
30         Dockerfile) already, pass a readable file-like object to ``fileobj``
31         and also pass ``custom_context=True``. If the stream is compressed
32         also, set ``encoding`` to the correct value (e.g ``gzip``).
33 
34         Example:
35             >>> from io import BytesIO
36             >>> from docker import APIClient
37             >>> dockerfile = '''
38             ... # Shared Volume
39             ... FROM busybox:buildroot-2014.02
40             ... VOLUME /data
41             ... CMD ["/bin/sh"]
42             ... '''
43             >>> f = BytesIO(dockerfile.encode('utf-8'))
44             >>> cli = APIClient(base_url='tcp://127.0.0.1:2375')
45             >>> response = [line for line in cli.build(
46             ...     fileobj=f, rm=True, tag='yourname/volume'
47             ... )]
48             >>> response
49             ['{"stream":" ---\\u003e a9eb17255234\\n"}',
50              '{"stream":"Step 1 : VOLUME /data\\n"}',
51              '{"stream":" ---\\u003e Running in abdc1e6896c6\\n"}',
52              '{"stream":" ---\\u003e 713bca62012e\\n"}',
53              '{"stream":"Removing intermediate container abdc1e6896c6\\n"}',
54              '{"stream":"Step 2 : CMD [\\"/bin/sh\\"]\\n"}',
55              '{"stream":" ---\\u003e Running in dba30f2a1a7e\\n"}',
56              '{"stream":" ---\\u003e 032b8b2855fc\\n"}',
57              '{"stream":"Removing intermediate container dba30f2a1a7e\\n"}',
58              '{"stream":"Successfully built 032b8b2855fc\\n"}']
59 
60         Args:
61             path (str): Path to the directory containing the Dockerfile
62             fileobj: A file object to use as the Dockerfile. (Or a file-like
63                 object)
64             tag (str): A tag to add to the final image
65             quiet (bool): Whether to return the status
66             nocache (bool): Don't use the cache when set to ``True``
67             rm (bool): Remove intermediate containers. The ``docker build``
68                 command now defaults to ``--rm=true``, but we have kept the old
69                 default of `False` to preserve backward compatibility
70             stream (bool): *Deprecated for API version > 1.8 (always True)*.
71                 Return a blocking generator you can iterate over to retrieve
72                 build output as it happens
73             timeout (int): HTTP timeout
74             custom_context (bool): Optional if using ``fileobj``
75             encoding (str): The encoding for a stream. Set to ``gzip`` for
76                 compressing
77             pull (bool): Downloads any updates to the FROM image in Dockerfiles
78             forcerm (bool): Always remove intermediate containers, even after
79                 unsuccessful builds
80             dockerfile (str): path within the build context to the Dockerfile
81             buildargs (dict): A dictionary of build arguments
82             container_limits (dict): A dictionary of limits applied to each
83                 container created by the build process. Valid keys:
84 
85                 - memory (int): set memory limit for build
86                 - memswap (int): Total memory (memory + swap), -1 to disable
87                     swap
88                 - cpushares (int): CPU shares (relative weight)
89                 - cpusetcpus (str): CPUs in which to allow execution, e.g.,
90                     ``"0-3"``, ``"0,1"``
91             decode (bool): If set to ``True``, the returned stream will be
92                 decoded into dicts on the fly. Default ``False``
93             shmsize (int): Size of `/dev/shm` in bytes. The size must be
94                 greater than 0. If omitted the system uses 64MB
95             labels (dict): A dictionary of labels to set on the image
96             cache_from (:py:class:`list`): A list of images used for build
97                 cache resolution
98             target (str): Name of the build-stage to build in a multi-stage
99                 Dockerfile
100             network_mode (str): networking mode for the run commands during
101                 build
102             squash (bool): Squash the resulting images layers into a
103                 single layer.
104             extra_hosts (dict): Extra hosts to add to /etc/hosts in building
105                 containers, as a mapping of hostname to IP address.
106 
107         Returns:
108             A generator for the build output.
109 
110         Raises:
111             :py:class:`docker.errors.APIError`
112                 If the server returns an error.
113             ``TypeError``
114                 If neither ``path`` nor ``fileobj`` is specified.
115         """
116         remote = context = None
117         headers = {}
118         container_limits = container_limits or {}
119         if path is None and fileobj is None:
120             raise TypeError("Either path or fileobj needs to be provided.")
121         if gzip and encoding is not None:
122             raise errors.DockerException(
123                 'Can not use custom encoding if gzip is enabled'
124             )
125 
126         for key in container_limits.keys():
127             if key not in constants.CONTAINER_LIMITS_KEYS:
128                 raise errors.DockerException(
129                     'Invalid container_limits key {0}'.format(key)
130                 )
131 
132         if custom_context:
133             if not fileobj:
134                 raise TypeError("You must specify fileobj with custom_context")
135             context = fileobj
136         elif fileobj is not None:
137             context = utils.mkbuildcontext(fileobj)
138         elif path.startswith(('http://', 'https://',
139                               'git://', 'github.com/', 'git@')):
140             remote = path
141         elif not os.path.isdir(path):
142             raise TypeError("You must specify a directory to build in path")
143         else:
144             dockerignore = os.path.join(path, '.dockerignore')
145             exclude = None
146             if os.path.exists(dockerignore):
147                 with open(dockerignore, 'r') as f:
148                     exclude = list(filter(bool, f.read().splitlines()))
149             context = utils.tar(
150                 path, exclude=exclude, dockerfile=dockerfile, gzip=gzip
151             )
152             encoding = 'gzip' if gzip else encoding
153 
154         if utils.compare_version('1.8', self._version) >= 0:
155             stream = True
156 
157         if dockerfile and utils.compare_version('1.17', self._version) < 0:
158             raise errors.InvalidVersion(
159                 'dockerfile was only introduced in API version 1.17'
160             )
161 
162         if utils.compare_version('1.19', self._version) < 0:
163             pull = 1 if pull else 0
164 
165         u = self._url('/build')
166         params = {
167             't': tag,
168             'remote': remote,
169             'q': quiet,
170             'nocache': nocache,
171             'rm': rm,
172             'forcerm': forcerm,
173             'pull': pull,
174             'dockerfile': dockerfile,
175         }
176         params.update(container_limits)
177 
178         if buildargs:
179             if utils.version_gte(self._version, '1.21'):
180                 params.update({'buildargs': json.dumps(buildargs)})
181             else:
182                 raise errors.InvalidVersion(
183                     'buildargs was only introduced in API version 1.21'
184                 )
185 
186         if shmsize:
187             if utils.version_gte(self._version, '1.22'):
188                 params.update({'shmsize': shmsize})
189             else:
190                 raise errors.InvalidVersion(
191                     'shmsize was only introduced in API version 1.22'
192                 )
193 
194         if labels:
195             if utils.version_gte(self._version, '1.23'):
196                 params.update({'labels': json.dumps(labels)})
197             else:
198                 raise errors.InvalidVersion(
199                     'labels was only introduced in API version 1.23'
200                 )
201 
202         if cache_from:
203             if utils.version_gte(self._version, '1.25'):
204                 params.update({'cachefrom': json.dumps(cache_from)})
205             else:
206                 raise errors.InvalidVersion(
207                     'cache_from was only introduced in API version 1.25'
208                 )
209 
210         if target:
211             if utils.version_gte(self._version, '1.29'):
212                 params.update({'target': target})
213             else:
214                 raise errors.InvalidVersion(
215                     'target was only introduced in API version 1.29'
216                 )
217 
218         if network_mode:
219             if utils.version_gte(self._version, '1.25'):
220                 params.update({'networkmode': network_mode})
221             else:
222                 raise errors.InvalidVersion(
223                     'network_mode was only introduced in API version 1.25'
224                 )
225 
226         if squash:
227             if utils.version_gte(self._version, '1.25'):
228                 params.update({'squash': squash})
229             else:
230                 raise errors.InvalidVersion(
231                     'squash was only introduced in API version 1.25'
232                 )
233 
234         if extra_hosts is not None:
235             if utils.version_lt(self._version, '1.27'):
236                 raise errors.InvalidVersion(
237                     'extra_hosts was only introduced in API version 1.27'
238                 )
239 
240             if isinstance(extra_hosts, dict):
241                 extra_hosts = utils.format_extra_hosts(extra_hosts)
242             params.update({'extrahosts': extra_hosts})
243 
244         if context is not None:
245             headers = {'Content-Type': 'application/tar'}
246             if encoding:
247                 headers['Content-Encoding'] = encoding
248 
249         if utils.compare_version('1.9', self._version) >= 0:
250             self._set_auth_headers(headers)
251 
252         response = self._post(
253             u,
254             data=context,
255             params=params,
256             headers=headers,
257             stream=stream,
258             timeout=timeout,
259         )
260 
261         if context is not None and not custom_context:
262             context.close()
263 
264         if stream:
265             return self._stream_helper(response, decode=decode)
266         else:
267             output = self._result(response)
268             srch = r'Successfully built ([0-9a-f]+)'
269             match = re.search(srch, output)
270             if not match:
271                 return None, output
272             return match.group(1), output
273 
274     def _set_auth_headers(self, headers):
275         log.debug('Looking for auth config')
276 
277         # If we don't have any auth data so far, try reloading the config
278         # file one more time in case anything showed up in there.
279         if not self._auth_configs:
280             log.debug("No auth config in memory - loading from filesystem")
281             self._auth_configs = auth.load_config()
282 
283         # Send the full auth configuration (if any exists), since the build
284         # could use any (or all) of the registries.
285         if self._auth_configs:
286             auth_data = {}
287             if self._auth_configs.get('credsStore'):
288                 # Using a credentials store, we need to retrieve the
289                 # credentials for each registry listed in the config.json file
290                 # Matches CLI behavior: https://github.com/docker/docker/blob/
291                 # 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/
292                 # credentials/native_store.go#L68-L83
293                 for registry in self._auth_configs.keys():
294                     if registry == 'credsStore' or registry == 'HttpHeaders':
295                         continue
296                     auth_data[registry] = auth.resolve_authconfig(
297                         self._auth_configs, registry
298                     )
299             else:
300                 auth_data = self._auth_configs.copy()
301                 # See https://github.com/docker/docker-py/issues/1683
302                 if auth.INDEX_NAME in auth_data:
303                     auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME]
304 
305             log.debug(
306                 'Sending auth config ({0})'.format(
307                     ', '.join(repr(k) for k in auth_data.keys())
308                 )
309             )
310 
311             if utils.compare_version('1.19', self._version) >= 0:
312                 headers['X-Registry-Config'] = auth.encode_header(
313                     auth_data
314                 )
315             else:
316                 headers['X-Registry-Config'] = auth.encode_header({
317                     'configs': auth_data
318                 })
319         else:
320             log.debug('No auth config found')
321
```
--- 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/api/build.py b/docker/api/build.py
--- a/docker/api/build.py
+++ b/docker/api/build.py
@@ -145,7 +145,9 @@
             exclude = None
             if os.path.exists(dockerignore):
                 with open(dockerignore, 'r') as f:
-                    exclude = list(filter(bool, f.read().splitlines()))
+                    exclude = list(filter(
+                        bool, [l.strip() for l in f.read().splitlines()]
+                    ))
             context = utils.tar(
                 path, exclude=exclude, dockerfile=dockerfile, gzip=gzip
             )

{"golden_diff": "diff --git a/docker/api/build.py b/docker/api/build.py\n--- a/docker/api/build.py\n+++ b/docker/api/build.py\n@@ -145,7 +145,9 @@\n             exclude = None\n             if os.path.exists(dockerignore):\n                 with open(dockerignore, 'r') as f:\n-                    exclude = list(filter(bool, f.read().splitlines()))\n+                    exclude = list(filter(\n+                        bool, [l.strip() for l in f.read().splitlines()]\n+                    ))\n             context = utils.tar(\n                 path, exclude=exclude, dockerfile=dockerfile, gzip=gzip\n             )\n", "issue": ".dockerignore file with space-only lines breaks build on Windows\nOriginally reported in https://github.com/docker/compose/issues/5526\n", "before_files": [{"content": "import json\nimport logging\nimport os\nimport re\n\nfrom .. import auth\nfrom .. import constants\nfrom .. import errors\nfrom .. import utils\n\n\nlog = logging.getLogger(__name__)\n\n\nclass BuildApiMixin(object):\n    def build(self, path=None, tag=None, quiet=False, fileobj=None,\n              nocache=False, rm=False, stream=False, timeout=None,\n              custom_context=False, encoding=None, pull=False,\n              forcerm=False, dockerfile=None, container_limits=None,\n              decode=False, buildargs=None, gzip=False, shmsize=None,\n              labels=None, cache_from=None, target=None, network_mode=None,\n              squash=None, extra_hosts=None):\n        \"\"\"\n        Similar to the ``docker build`` command. Either ``path`` or ``fileobj``\n        needs to be set. ``path`` can be a local path (to a directory\n        containing a Dockerfile) or a remote URL. ``fileobj`` must be a\n        readable file-like object to a Dockerfile.\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        Example:\n            >>> from io import BytesIO\n            >>> from docker import APIClient\n            >>> dockerfile = '''\n            ... # Shared Volume\n            ... FROM busybox:buildroot-2014.02\n            ... VOLUME /data\n            ... CMD [\"/bin/sh\"]\n            ... '''\n            >>> f = BytesIO(dockerfile.encode('utf-8'))\n            >>> cli = APIClient(base_url='tcp://127.0.0.1:2375')\n            >>> response = [line for line in cli.build(\n            ...     fileobj=f, rm=True, tag='yourname/volume'\n            ... )]\n            >>> response\n            ['{\"stream\":\" ---\\\\u003e a9eb17255234\\\\n\"}',\n             '{\"stream\":\"Step 1 : VOLUME /data\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e Running in abdc1e6896c6\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e 713bca62012e\\\\n\"}',\n             '{\"stream\":\"Removing intermediate container abdc1e6896c6\\\\n\"}',\n             '{\"stream\":\"Step 2 : CMD [\\\\\"/bin/sh\\\\\"]\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e Running in dba30f2a1a7e\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e 032b8b2855fc\\\\n\"}',\n             '{\"stream\":\"Removing intermediate container dba30f2a1a7e\\\\n\"}',\n             '{\"stream\":\"Successfully built 032b8b2855fc\\\\n\"}']\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            shmsize (int): Size of `/dev/shm` in bytes. The size must be\n                greater than 0. If omitted the system uses 64MB\n            labels (dict): A dictionary of labels to set on the image\n            cache_from (:py:class:`list`): A list of images used for build\n                cache resolution\n            target (str): Name of the build-stage to build in a multi-stage\n                Dockerfile\n            network_mode (str): networking mode for the run commands during\n                build\n            squash (bool): Squash the resulting images layers into a\n                single layer.\n            extra_hosts (dict): Extra hosts to add to /etc/hosts in building\n                containers, as a mapping of hostname to IP address.\n\n        Returns:\n            A generator for the build output.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n            ``TypeError``\n                If neither ``path`` nor ``fileobj`` is specified.\n        \"\"\"\n        remote = context = None\n        headers = {}\n        container_limits = container_limits or {}\n        if path is None and fileobj is None:\n            raise TypeError(\"Either path or fileobj needs to be provided.\")\n        if gzip and encoding is not None:\n            raise errors.DockerException(\n                'Can not use custom encoding if gzip is enabled'\n            )\n\n        for key in container_limits.keys():\n            if key not in constants.CONTAINER_LIMITS_KEYS:\n                raise errors.DockerException(\n                    'Invalid container_limits key {0}'.format(key)\n                )\n\n        if custom_context:\n            if not fileobj:\n                raise TypeError(\"You must specify fileobj with custom_context\")\n            context = fileobj\n        elif fileobj is not None:\n            context = utils.mkbuildcontext(fileobj)\n        elif path.startswith(('http://', 'https://',\n                              'git://', 'github.com/', 'git@')):\n            remote = path\n        elif not os.path.isdir(path):\n            raise TypeError(\"You must specify a directory to build in path\")\n        else:\n            dockerignore = os.path.join(path, '.dockerignore')\n            exclude = None\n            if os.path.exists(dockerignore):\n                with open(dockerignore, 'r') as f:\n                    exclude = list(filter(bool, f.read().splitlines()))\n            context = utils.tar(\n                path, exclude=exclude, dockerfile=dockerfile, gzip=gzip\n            )\n            encoding = 'gzip' if gzip else encoding\n\n        if utils.compare_version('1.8', self._version) >= 0:\n            stream = True\n\n        if dockerfile and utils.compare_version('1.17', self._version) < 0:\n            raise errors.InvalidVersion(\n                'dockerfile was only introduced in API version 1.17'\n            )\n\n        if utils.compare_version('1.19', self._version) < 0:\n            pull = 1 if pull else 0\n\n        u = self._url('/build')\n        params = {\n            't': tag,\n            'remote': remote,\n            'q': quiet,\n            'nocache': nocache,\n            'rm': rm,\n            'forcerm': forcerm,\n            'pull': pull,\n            'dockerfile': dockerfile,\n        }\n        params.update(container_limits)\n\n        if buildargs:\n            if utils.version_gte(self._version, '1.21'):\n                params.update({'buildargs': json.dumps(buildargs)})\n            else:\n                raise errors.InvalidVersion(\n                    'buildargs was only introduced in API version 1.21'\n                )\n\n        if shmsize:\n            if utils.version_gte(self._version, '1.22'):\n                params.update({'shmsize': shmsize})\n            else:\n                raise errors.InvalidVersion(\n                    'shmsize was only introduced in API version 1.22'\n                )\n\n        if labels:\n            if utils.version_gte(self._version, '1.23'):\n                params.update({'labels': json.dumps(labels)})\n            else:\n                raise errors.InvalidVersion(\n                    'labels was only introduced in API version 1.23'\n                )\n\n        if cache_from:\n            if utils.version_gte(self._version, '1.25'):\n                params.update({'cachefrom': json.dumps(cache_from)})\n            else:\n                raise errors.InvalidVersion(\n                    'cache_from was only introduced in API version 1.25'\n                )\n\n        if target:\n            if utils.version_gte(self._version, '1.29'):\n                params.update({'target': target})\n            else:\n                raise errors.InvalidVersion(\n                    'target was only introduced in API version 1.29'\n                )\n\n        if network_mode:\n            if utils.version_gte(self._version, '1.25'):\n                params.update({'networkmode': network_mode})\n            else:\n                raise errors.InvalidVersion(\n                    'network_mode was only introduced in API version 1.25'\n                )\n\n        if squash:\n            if utils.version_gte(self._version, '1.25'):\n                params.update({'squash': squash})\n            else:\n                raise errors.InvalidVersion(\n                    'squash was only introduced in API version 1.25'\n                )\n\n        if extra_hosts is not None:\n            if utils.version_lt(self._version, '1.27'):\n                raise errors.InvalidVersion(\n                    'extra_hosts was only introduced in API version 1.27'\n                )\n\n            if isinstance(extra_hosts, dict):\n                extra_hosts = utils.format_extra_hosts(extra_hosts)\n            params.update({'extrahosts': extra_hosts})\n\n        if context is not None:\n            headers = {'Content-Type': 'application/tar'}\n            if encoding:\n                headers['Content-Encoding'] = encoding\n\n        if utils.compare_version('1.9', self._version) >= 0:\n            self._set_auth_headers(headers)\n\n        response = self._post(\n            u,\n            data=context,\n            params=params,\n            headers=headers,\n            stream=stream,\n            timeout=timeout,\n        )\n\n        if context is not None and not custom_context:\n            context.close()\n\n        if stream:\n            return self._stream_helper(response, decode=decode)\n        else:\n            output = self._result(response)\n            srch = r'Successfully built ([0-9a-f]+)'\n            match = re.search(srch, output)\n            if not match:\n                return None, output\n            return match.group(1), output\n\n    def _set_auth_headers(self, headers):\n        log.debug('Looking for auth config')\n\n        # If we don't have any auth data so far, try reloading the config\n        # file one more time in case anything showed up in there.\n        if not self._auth_configs:\n            log.debug(\"No auth config in memory - loading from filesystem\")\n            self._auth_configs = auth.load_config()\n\n        # Send the full auth configuration (if any exists), since the build\n        # could use any (or all) of the registries.\n        if self._auth_configs:\n            auth_data = {}\n            if self._auth_configs.get('credsStore'):\n                # Using a credentials store, we need to retrieve the\n                # credentials for each registry listed in the config.json file\n                # Matches CLI behavior: https://github.com/docker/docker/blob/\n                # 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/\n                # credentials/native_store.go#L68-L83\n                for registry in self._auth_configs.keys():\n                    if registry == 'credsStore' or registry == 'HttpHeaders':\n                        continue\n                    auth_data[registry] = auth.resolve_authconfig(\n                        self._auth_configs, registry\n                    )\n            else:\n                auth_data = self._auth_configs.copy()\n                # See https://github.com/docker/docker-py/issues/1683\n                if auth.INDEX_NAME in auth_data:\n                    auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME]\n\n            log.debug(\n                'Sending auth config ({0})'.format(\n                    ', '.join(repr(k) for k in auth_data.keys())\n                )\n            )\n\n            if utils.compare_version('1.19', self._version) >= 0:\n                headers['X-Registry-Config'] = auth.encode_header(\n                    auth_data\n                )\n            else:\n                headers['X-Registry-Config'] = auth.encode_header({\n                    'configs': auth_data\n                })\n        else:\n            log.debug('No auth config found')\n", "path": "docker/api/build.py"}], "after_files": [{"content": "import json\nimport logging\nimport os\nimport re\n\nfrom .. import auth\nfrom .. import constants\nfrom .. import errors\nfrom .. import utils\n\n\nlog = logging.getLogger(__name__)\n\n\nclass BuildApiMixin(object):\n    def build(self, path=None, tag=None, quiet=False, fileobj=None,\n              nocache=False, rm=False, stream=False, timeout=None,\n              custom_context=False, encoding=None, pull=False,\n              forcerm=False, dockerfile=None, container_limits=None,\n              decode=False, buildargs=None, gzip=False, shmsize=None,\n              labels=None, cache_from=None, target=None, network_mode=None,\n              squash=None, extra_hosts=None):\n        \"\"\"\n        Similar to the ``docker build`` command. Either ``path`` or ``fileobj``\n        needs to be set. ``path`` can be a local path (to a directory\n        containing a Dockerfile) or a remote URL. ``fileobj`` must be a\n        readable file-like object to a Dockerfile.\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        Example:\n            >>> from io import BytesIO\n            >>> from docker import APIClient\n            >>> dockerfile = '''\n            ... # Shared Volume\n            ... FROM busybox:buildroot-2014.02\n            ... VOLUME /data\n            ... CMD [\"/bin/sh\"]\n            ... '''\n            >>> f = BytesIO(dockerfile.encode('utf-8'))\n            >>> cli = APIClient(base_url='tcp://127.0.0.1:2375')\n            >>> response = [line for line in cli.build(\n            ...     fileobj=f, rm=True, tag='yourname/volume'\n            ... )]\n            >>> response\n            ['{\"stream\":\" ---\\\\u003e a9eb17255234\\\\n\"}',\n             '{\"stream\":\"Step 1 : VOLUME /data\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e Running in abdc1e6896c6\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e 713bca62012e\\\\n\"}',\n             '{\"stream\":\"Removing intermediate container abdc1e6896c6\\\\n\"}',\n             '{\"stream\":\"Step 2 : CMD [\\\\\"/bin/sh\\\\\"]\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e Running in dba30f2a1a7e\\\\n\"}',\n             '{\"stream\":\" ---\\\\u003e 032b8b2855fc\\\\n\"}',\n             '{\"stream\":\"Removing intermediate container dba30f2a1a7e\\\\n\"}',\n             '{\"stream\":\"Successfully built 032b8b2855fc\\\\n\"}']\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            shmsize (int): Size of `/dev/shm` in bytes. The size must be\n                greater than 0. If omitted the system uses 64MB\n            labels (dict): A dictionary of labels to set on the image\n            cache_from (:py:class:`list`): A list of images used for build\n                cache resolution\n            target (str): Name of the build-stage to build in a multi-stage\n                Dockerfile\n            network_mode (str): networking mode for the run commands during\n                build\n            squash (bool): Squash the resulting images layers into a\n                single layer.\n            extra_hosts (dict): Extra hosts to add to /etc/hosts in building\n                containers, as a mapping of hostname to IP address.\n\n        Returns:\n            A generator for the build output.\n\n        Raises:\n            :py:class:`docker.errors.APIError`\n                If the server returns an error.\n            ``TypeError``\n                If neither ``path`` nor ``fileobj`` is specified.\n        \"\"\"\n        remote = context = None\n        headers = {}\n        container_limits = container_limits or {}\n        if path is None and fileobj is None:\n            raise TypeError(\"Either path or fileobj needs to be provided.\")\n        if gzip and encoding is not None:\n            raise errors.DockerException(\n                'Can not use custom encoding if gzip is enabled'\n            )\n\n        for key in container_limits.keys():\n            if key not in constants.CONTAINER_LIMITS_KEYS:\n                raise errors.DockerException(\n                    'Invalid container_limits key {0}'.format(key)\n                )\n\n        if custom_context:\n            if not fileobj:\n                raise TypeError(\"You must specify fileobj with custom_context\")\n            context = fileobj\n        elif fileobj is not None:\n            context = utils.mkbuildcontext(fileobj)\n        elif path.startswith(('http://', 'https://',\n                              'git://', 'github.com/', 'git@')):\n            remote = path\n        elif not os.path.isdir(path):\n            raise TypeError(\"You must specify a directory to build in path\")\n        else:\n            dockerignore = os.path.join(path, '.dockerignore')\n            exclude = None\n            if os.path.exists(dockerignore):\n                with open(dockerignore, 'r') as f:\n                    exclude = list(filter(\n                        bool, [l.strip() for l in f.read().splitlines()]\n                    ))\n            context = utils.tar(\n                path, exclude=exclude, dockerfile=dockerfile, gzip=gzip\n            )\n            encoding = 'gzip' if gzip else encoding\n\n        if utils.compare_version('1.8', self._version) >= 0:\n            stream = True\n\n        if dockerfile and utils.compare_version('1.17', self._version) < 0:\n            raise errors.InvalidVersion(\n                'dockerfile was only introduced in API version 1.17'\n            )\n\n        if utils.compare_version('1.19', self._version) < 0:\n            pull = 1 if pull else 0\n\n        u = self._url('/build')\n        params = {\n            't': tag,\n            'remote': remote,\n            'q': quiet,\n            'nocache': nocache,\n            'rm': rm,\n            'forcerm': forcerm,\n            'pull': pull,\n            'dockerfile': dockerfile,\n        }\n        params.update(container_limits)\n\n        if buildargs:\n            if utils.version_gte(self._version, '1.21'):\n                params.update({'buildargs': json.dumps(buildargs)})\n            else:\n                raise errors.InvalidVersion(\n                    'buildargs was only introduced in API version 1.21'\n                )\n\n        if shmsize:\n            if utils.version_gte(self._version, '1.22'):\n                params.update({'shmsize': shmsize})\n            else:\n                raise errors.InvalidVersion(\n                    'shmsize was only introduced in API version 1.22'\n                )\n\n        if labels:\n            if utils.version_gte(self._version, '1.23'):\n                params.update({'labels': json.dumps(labels)})\n            else:\n                raise errors.InvalidVersion(\n                    'labels was only introduced in API version 1.23'\n                )\n\n        if cache_from:\n            if utils.version_gte(self._version, '1.25'):\n                params.update({'cachefrom': json.dumps(cache_from)})\n            else:\n                raise errors.InvalidVersion(\n                    'cache_from was only introduced in API version 1.25'\n                )\n\n        if target:\n            if utils.version_gte(self._version, '1.29'):\n                params.update({'target': target})\n            else:\n                raise errors.InvalidVersion(\n                    'target was only introduced in API version 1.29'\n                )\n\n        if network_mode:\n            if utils.version_gte(self._version, '1.25'):\n                params.update({'networkmode': network_mode})\n            else:\n                raise errors.InvalidVersion(\n                    'network_mode was only introduced in API version 1.25'\n                )\n\n        if squash:\n            if utils.version_gte(self._version, '1.25'):\n                params.update({'squash': squash})\n            else:\n                raise errors.InvalidVersion(\n                    'squash was only introduced in API version 1.25'\n                )\n\n        if extra_hosts is not None:\n            if utils.version_lt(self._version, '1.27'):\n                raise errors.InvalidVersion(\n                    'extra_hosts was only introduced in API version 1.27'\n                )\n\n            if isinstance(extra_hosts, dict):\n                extra_hosts = utils.format_extra_hosts(extra_hosts)\n            params.update({'extrahosts': extra_hosts})\n\n        if context is not None:\n            headers = {'Content-Type': 'application/tar'}\n            if encoding:\n                headers['Content-Encoding'] = encoding\n\n        if utils.compare_version('1.9', self._version) >= 0:\n            self._set_auth_headers(headers)\n\n        response = self._post(\n            u,\n            data=context,\n            params=params,\n            headers=headers,\n            stream=stream,\n            timeout=timeout,\n        )\n\n        if context is not None and not custom_context:\n            context.close()\n\n        if stream:\n            return self._stream_helper(response, decode=decode)\n        else:\n            output = self._result(response)\n            srch = r'Successfully built ([0-9a-f]+)'\n            match = re.search(srch, output)\n            if not match:\n                return None, output\n            return match.group(1), output\n\n    def _set_auth_headers(self, headers):\n        log.debug('Looking for auth config')\n\n        # If we don't have any auth data so far, try reloading the config\n        # file one more time in case anything showed up in there.\n        if not self._auth_configs:\n            log.debug(\"No auth config in memory - loading from filesystem\")\n            self._auth_configs = auth.load_config()\n\n        # Send the full auth configuration (if any exists), since the build\n        # could use any (or all) of the registries.\n        if self._auth_configs:\n            auth_data = {}\n            if self._auth_configs.get('credsStore'):\n                # Using a credentials store, we need to retrieve the\n                # credentials for each registry listed in the config.json file\n                # Matches CLI behavior: https://github.com/docker/docker/blob/\n                # 67b85f9d26f1b0b2b240f2d794748fac0f45243c/cliconfig/\n                # credentials/native_store.go#L68-L83\n                for registry in self._auth_configs.keys():\n                    if registry == 'credsStore' or registry == 'HttpHeaders':\n                        continue\n                    auth_data[registry] = auth.resolve_authconfig(\n                        self._auth_configs, registry\n                    )\n            else:\n                auth_data = self._auth_configs.copy()\n                # See https://github.com/docker/docker-py/issues/1683\n                if auth.INDEX_NAME in auth_data:\n                    auth_data[auth.INDEX_URL] = auth_data[auth.INDEX_NAME]\n\n            log.debug(\n                'Sending auth config ({0})'.format(\n                    ', '.join(repr(k) for k in auth_data.keys())\n                )\n            )\n\n            if utils.compare_version('1.19', self._version) >= 0:\n                headers['X-Registry-Config'] = auth.encode_header(\n                    auth_data\n                )\n            else:\n                headers['X-Registry-Config'] = auth.encode_header({\n                    'configs': auth_data\n                })\n        else:\n            log.debug('No auth config found')\n", "path": "docker/api/build.py"}]}