def extract(self, bucket, archive, files):
        """API binding of `extract`.

        @param bucket: The bucket of the file on GS.
        @param archive: The path of archive on GS (bucket part not included).
        @param files: A list of files to be extracted.

        @return A dict of extracted files, in format of
                {filename: content, ...}.
        @throws ResponseContentError if the response is not in JSON format.
        """
        rsp_contents = []
        # The files to be extract may be too many which reuslts in too long URL
        # and http server may responses with 414 error. So we split them into
        # multiple requests if necessary.
        for part_of_files in string_utils.join_longest_with_length_limit(
                files, _MAX_URL_QUERY_LENGTH, separator='&file=',
                do_join=False):
            rsp_contents.append(
                self._call('extract', bucket, archive,
                           {'file': part_of_files}))
        content_dict = {}
        try:
            for content in rsp_contents:
                content_dict.update(json.loads(content))
        except ValueError as err:
            raise ResponseContentError(
                'Got ValueError "%s" when decoding to JSON format. The '
                'response content is: %s' % (err, rsp_contents))

        return content_dict
 def test_long_sep(self):
     """Test with long seperator."""
     result = list(
         string_utils.join_longest_with_length_limit(
             self.strings, 6, separator='|very long separator|'))
     # Though the string to be joined is short, we still will have 3 result
     # because each of them plus separator is longer than the limit.
     self.assertEqual(len(result), 3)
 def test_short_strings(self):
     """Test with short strings to be joined with big limit."""
     sep = mock.MagicMock()
     result = list(
         string_utils.join_longest_with_length_limit(self.strings,
                                                     100,
                                                     separator=sep))
     sep.join.assert_called_once()
 def test_basic(self):
     """The basic test case."""
     result = list(
         string_utils.join_longest_with_length_limit(self.strings,
                                                     6,
                                                     separator=','))
     self.assertEqual(len(result), 2)
     self.assertTrue(type(result[0]) is str)
 def test_do_not_join(self):
     """Test yielding list instead of string."""
     result = list(
         string_utils.join_longest_with_length_limit(self.strings,
                                                     6,
                                                     separator=',',
                                                     do_join=False))
     self.assertEqual(len(result), 2)
     self.assertTrue(type(result[0]) is list)
 def test_string_too_long(self):
     """Test with too long string to be joined."""
     strings = ['abc', '12', 'sssss', 'a very long long long string']
     with self.assertRaises(string_utils.StringTooLongError):
         list(string_utils.join_longest_with_length_limit(strings, 6))