Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: rename 'Blob.download_as_{string,bytes}', add 'Blob.download_as_text' #182

Merged
merged 10 commits into from Aug 10, 2020
16 changes: 14 additions & 2 deletions google/cloud/storage/blob.py
Expand Up @@ -1192,11 +1192,14 @@ def download_as_string(
if_metageneration_not_match=None,
timeout=_DEFAULT_TIMEOUT,
):
"""Download the contents of this blob as a bytes object.
"""(Deprecated) Download the contents of this blob as a bytes object.

If :attr:`user_project` is set on the bucket, bills the API request
to that project.

.. note::
Deprecated alias for :meth:`download_as_bytes`.

:type client: :class:`~google.cloud.storage.client.Client` or
``NoneType``
:param client: (Optional) The client to use. If not passed, falls back
Expand Down Expand Up @@ -1245,6 +1248,12 @@ def download_as_string(

:raises: :class:`google.cloud.exceptions.NotFound`
"""
tseaver marked this conversation as resolved.
Show resolved Hide resolved
warnings.warn(
"Blob.download_as_string() is deprecated and will be removed in future."
"Use Blob.download_as_bytes() instead.",
PendingDeprecationWarning,
stacklevel=1,
)
return self.download_as_bytes(
client=client,
start=start,
Expand Down Expand Up @@ -1340,7 +1349,10 @@ def download_as_text(
timeout=timeout,
)
if six.PY2:
tseaver marked this conversation as resolved.
Show resolved Hide resolved
return data
if self.content_encoding:
return data.decode(self.content_encoding)
else:
return data.decode(encoding)
else:
if self.content_encoding:
return data.decode(self.content_encoding)
Expand Down
60 changes: 59 additions & 1 deletion tests/unit/test_blob.py
Expand Up @@ -1448,6 +1448,56 @@ def _download_as_bytes_helper(self, raw_download, timeout=None):
stream = blob._do_download.mock_calls[0].args[1]
self.assertIsInstance(stream, io.BytesIO)

def test_download_as_string_w_response_headers(self):
blob_name = "blob-name"
client = mock.Mock(spec=["_http"])
bucket = _Bucket(client)
media_link = "http://example.com/media/"
properties = {"mediaLink": media_link}
blob = self._make_one(blob_name, bucket=bucket, properties=properties)

response = self._mock_requests_response(
http_client.OK,
headers={
"Content-Type": "application/json",
"Content-Language": "ko-kr",
"Cache-Control": "max-age=1337;public",
"Content-Encoding": "gzip",
"X-Goog-Storage-Class": "STANDARD",
"X-Goog-Hash": "crc32c=4gcgLQ==,md5=CS9tHYTtyFntzj7B9nkkJQ==",
},
# { "x": 5 } gzipped
content=b"\x1f\x8b\x08\x00\xcfo\x17_\x02\xff\xabVP\xaaP\xb2R0U\xa8\x05\x00\xa1\xcaQ\x93\n\x00\x00\x00",
)
blob._extract_headers_from_download(response)

self.assertEqual(blob.content_type, "application/json")
self.assertEqual(blob.content_language, "ko-kr")
self.assertEqual(blob.content_encoding, "gzip")
self.assertEqual(blob.cache_control, "max-age=1337;public")
self.assertEqual(blob.storage_class, "STANDARD")
self.assertEqual(blob.md5_hash, "CS9tHYTtyFntzj7B9nkkJQ")
self.assertEqual(blob.crc32c, "4gcgLQ")

def test_download_as_string_w_hash_response_header_none(self):
blob_name = "blob-name"
client = mock.Mock(spec=["_http"])
bucket = _Bucket(client)
media_link = "http://example.com/media/"
properties = {"mediaLink": media_link}
blob = self._make_one(blob_name, bucket=bucket, properties=properties)

response = self._mock_requests_response(
http_client.OK,
headers={"X-Goog-Hash": ""},
# { "x": 5 } gzipped
content=b"\x1f\x8b\x08\x00\xcfo\x17_\x02\xff\xabVP\xaaP\xb2R0U\xa8\x05\x00\xa1\xcaQ\x93\n\x00\x00\x00",
)
blob._extract_headers_from_download(response)

self.assertIsNone(blob.md5_hash)
self.assertIsNone(blob.crc32c)

def test_download_as_bytes_w_generation_match(self):
GENERATION_NUMBER = 6
MEDIA_LINK = "http://example.com/media/"
Expand Down Expand Up @@ -1555,7 +1605,8 @@ def test_download_as_text_w_custom_timeout(self):
def test_download_as_text_w_encoding(self):
self._download_as_text_helper(raw_download=False, encoding="utf-8")

def test_download_as_string(self):
@mock.patch("warnings.warn")
def test_download_as_string(self, mock_warn):
MEDIA_LINK = "http://example.com/media/"

client = mock.Mock(spec=["_http"])
Expand All @@ -1580,6 +1631,13 @@ def test_download_as_string(self):
timeout=self._get_default_timeout(),
)

mock_warn.assert_called_with(
"Blob.download_as_string() is deprecated and will be removed in future."
"Use Blob.download_as_bytes() instead.",
PendingDeprecationWarning,
stacklevel=1,
)

def test__get_content_type_explicit(self):
blob = self._make_one(u"blob-name", bucket=None)

Expand Down