Repository: docker/docker-py

Issue:
returning the docker image details after docker load
Currently, load_image does not return any information about the image being currently loaded, even though the docker daemon returns this information. This would be a critical information, otherwise this detail needs to be sent along with the docker image archive separately in a manifest file.

The "docker load" CLI displays this detail


Discussion:

Resolving patch:
diff --git a/docker/api/image.py b/docker/api/image.py
--- a/docker/api/image.py
+++ b/docker/api/image.py
@@ -262,7 +262,7 @@ def inspect_image(self, image):
             self._get(self._url("/images/{0}/json", image)), True
         )
 
-    def load_image(self, data):
+    def load_image(self, data, quiet=None):
         """
         Load an image that was previously saved using
         :py:meth:`~docker.api.image.ImageApiMixin.get_image` (or ``docker
@@ -270,9 +270,32 @@ def load_image(self, data):
 
         Args:
             data (binary): Image data to be loaded.
+            quiet (boolean): Suppress progress details in response.
+
+        Returns:
+            (generator): Progress output as JSON objects. Only available for
+                         API version >= 1.23
+
+        Raises:
+            :py:class:`docker.errors.APIError`
+                If the server returns an error.
         """
-        res = self._post(self._url("/images/load"), data=data)
-        return self._result(res, True)
+        params = {}
+
+        if quiet is not None:
+            if utils.version_lt(self._version, '1.23'):
+                raise errors.InvalidVersion(
+                    'quiet is not supported in API version < 1.23'
+                )
+            params['quiet'] = quiet
+
+        res = self._post(
+            self._url("/images/load"), data=data, params=params, stream=True
+        )
+        if utils.version_gte(self._version, '1.23'):
+            return self._stream_helper(res, decode=True)
+
+        self._raise_for_status(res)
 
     @utils.minimum_version('1.25')
     def prune_images(self, filters=None):
diff --git a/docker/models/images.py b/docker/models/images.py
--- a/docker/models/images.py
+++ b/docker/models/images.py
@@ -235,6 +235,9 @@ def load(self, data):
         Args:
             data (binary): Image data to be loaded.
 
+        Returns:
+            (generator): Progress output as JSON objects
+
         Raises:
             :py:class:`docker.errors.APIError`
                 If the server returns an error.


Test patch:
diff --git a/tests/integration/api_image_test.py b/tests/integration/api_image_test.py
--- a/tests/integration/api_image_test.py
+++ b/tests/integration/api_image_test.py
@@ -249,6 +249,19 @@ def test_import_image_with_changes(self):
         assert img_data['Config']['Cmd'] == ['echo']
         assert img_data['Config']['User'] == 'foobar'
 
+    # Docs say output is available in 1.23, but this test fails on 1.12.0
+    @requires_api_version('1.24')
+    def test_get_load_image(self):
+        test_img = 'hello-world:latest'
+        self.client.pull(test_img)
+        data = self.client.get_image(test_img)
+        assert data
+        output = self.client.load_image(data)
+        assert any([
+            line for line in output
+            if 'Loaded image: {}'.format(test_img) in line.get('stream', '')
+        ])
+
     @contextlib.contextmanager
     def temporary_http_file_server(self, stream):
         '''Serve data from an IO stream over HTTP.'''
diff --git a/tests/unit/api_image_test.py b/tests/unit/api_image_test.py
--- a/tests/unit/api_image_test.py
+++ b/tests/unit/api_image_test.py
@@ -369,5 +369,19 @@ def test_load_image(self):
             'POST',
             url_prefix + 'images/load',
             data='Byte Stream....',
+            stream=True,
+            params={},
+            timeout=DEFAULT_TIMEOUT_SECONDS
+        )
+
+    def test_load_image_quiet(self):
+        self.client.load_image('Byte Stream....', quiet=True)
+
+        fake_request.assert_called_with(
+            'POST',
+            url_prefix + 'images/load',
+            data='Byte Stream....',
+            stream=True,
+            params={'quiet': True},
             timeout=DEFAULT_TIMEOUT_SECONDS
         )