Skip to content

fix: Changed name of methods Blob.from_string() and Bucket.from_string() to from_uri() #1335

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

Merged
merged 1 commit into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions google/cloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@
"Blob.download_as_string() is deprecated and will be removed in future. "
"Use Blob.download_as_bytes() instead."
)
_FROM_STRING_DEPRECATED = (
"Blob.from_string() is deprecated and will be removed in future. "
"Use Blob.from_uri() instead."
)
_GS_URL_REGEX_PATTERN = re.compile(
r"(?P<scheme>gs)://(?P<bucket_name>[a-z0-9_.-]+)/(?P<object_name>.+)"
)
Expand Down Expand Up @@ -387,15 +391,15 @@ def public_url(self):
)

@classmethod
def from_string(cls, uri, client=None):
def from_uri(cls, uri, client=None):
"""Get a constructor for blob object by URI.

.. code-block:: python

from google.cloud import storage
from google.cloud.storage.blob import Blob
client = storage.Client()
blob = Blob.from_string("gs://bucket/object", client=client)
blob = Blob.from_uri("gs://bucket/object", client=client)

:type uri: str
:param uri: The blob uri following a gs://bucket/object pattern.
Expand All @@ -417,6 +421,35 @@ def from_string(cls, uri, client=None):
bucket = Bucket(client, name=match.group("bucket_name"))
return cls(match.group("object_name"), bucket)

@classmethod
def from_string(cls, uri, client=None):
"""(Deprecated) Get a constructor for blob object by URI.

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

.. code-block:: python

from google.cloud import storage
from google.cloud.storage.blob import Blob
client = storage.Client()
blob = Blob.from_string("gs://bucket/object", client=client)

:type uri: str
:param uri: The blob uri following a gs://bucket/object pattern.
Both a bucket and object name is required to construct a blob object.

:type client: :class:`~google.cloud.storage.client.Client`
:param client:
(Optional) The client to use. Application code should
*always* pass ``client``.

:rtype: :class:`google.cloud.storage.blob.Blob`
:returns: The blob object created.
"""
warnings.warn(_FROM_STRING_DEPRECATED, PendingDeprecationWarning, stacklevel=2)
return Blob.from_uri(uri=uri, client=client)

def generate_signed_url(
self,
expiration=None,
Expand Down
35 changes: 33 additions & 2 deletions google/cloud/storage/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
"valid before the bucket is created. Instead, pass the location "
"to `Bucket.create`."
)
_FROM_STRING_MESSAGE = (
"Bucket.from_string() is deprecated. " "Use Bucket.from_uri() instead."
)


def _blobs_page_start(iterator, page, response):
Expand Down Expand Up @@ -726,15 +729,15 @@ def user_project(self):
return self._user_project

@classmethod
def from_string(cls, uri, client=None):
def from_uri(cls, uri, client=None):
"""Get a constructor for bucket object by URI.

.. code-block:: python

from google.cloud import storage
from google.cloud.storage.bucket import Bucket
client = storage.Client()
bucket = Bucket.from_string("gs://bucket", client=client)
bucket = Bucket.from_uri("gs://bucket", client=client)

:type uri: str
:param uri: The bucket uri pass to get bucket object.
Expand All @@ -754,6 +757,34 @@ def from_string(cls, uri, client=None):

return cls(client, name=netloc)

@classmethod
def from_string(cls, uri, client=None):
"""Get a constructor for bucket object by URI.

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

.. code-block:: python

from google.cloud import storage
from google.cloud.storage.bucket import Bucket
client = storage.Client()
bucket = Bucket.from_string("gs://bucket", client=client)

:type uri: str
:param uri: The bucket uri pass to get bucket object.

:type client: :class:`~google.cloud.storage.client.Client` or
``NoneType``
:param client: (Optional) The client to use. Application code should
*always* pass ``client``.

:rtype: :class:`google.cloud.storage.bucket.Bucket`
:returns: The bucket object created.
"""
warnings.warn(_FROM_STRING_MESSAGE, PendingDeprecationWarning, stacklevel=2)
return Bucket.from_uri(uri=uri, client=client)

def blob(
self,
blob_name,
Expand Down
2 changes: 1 addition & 1 deletion google/cloud/storage/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1148,7 +1148,7 @@ def download_blob_to_file(
"""

if not isinstance(blob_or_uri, Blob):
blob_or_uri = Blob.from_string(blob_or_uri)
blob_or_uri = Blob.from_uri(blob_or_uri)

blob_or_uri._prep_and_do_download(
file_obj,
Expand Down
42 changes: 35 additions & 7 deletions tests/unit/test_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -5876,46 +5876,74 @@ def test_soft_hard_delte_time_unset(self):
self.assertIsNone(blob.soft_delete_time)
self.assertIsNone(blob.hard_delete_time)

def test_from_string_w_valid_uri(self):
def test_from_uri_w_valid_uri(self):
from google.cloud.storage.blob import Blob

client = self._make_client()
basic_uri = "gs://bucket_name/b"
blob = Blob.from_string(basic_uri, client)
blob = Blob.from_uri(basic_uri, client)

self.assertIsInstance(blob, Blob)
self.assertIs(blob.client, client)
self.assertEqual(blob.name, "b")
self.assertEqual(blob.bucket.name, "bucket_name")

nested_uri = "gs://bucket_name/path1/path2/b#name"
blob = Blob.from_string(nested_uri, client)
blob = Blob.from_uri(nested_uri, client)

self.assertIsInstance(blob, Blob)
self.assertIs(blob.client, client)
self.assertEqual(blob.name, "path1/path2/b#name")
self.assertEqual(blob.bucket.name, "bucket_name")

def test_from_string_w_invalid_uri(self):
def test_from_uri_w_invalid_uri(self):
from google.cloud.storage.blob import Blob

client = self._make_client()

with pytest.raises(ValueError):
Blob.from_string("http://bucket_name/b", client)
Blob.from_uri("http://bucket_name/b", client)

def test_from_string_w_domain_name_bucket(self):
def test_from_uri_w_domain_name_bucket(self):
from google.cloud.storage.blob import Blob

client = self._make_client()
uri = "gs://buckets.example.com/b"
blob = Blob.from_string(uri, client)
blob = Blob.from_uri(uri, client)

self.assertIsInstance(blob, Blob)
self.assertIs(blob.client, client)
self.assertEqual(blob.name, "b")
self.assertEqual(blob.bucket.name, "buckets.example.com")

@mock.patch("warnings.warn")
def test_from_string(self, mock_warn):
from google.cloud.storage.blob import _FROM_STRING_DEPRECATED
from google.cloud.storage.blob import Blob

client = self._make_client()
basic_uri = "gs://bucket_name/b"
blob = Blob.from_string(basic_uri, client)

self.assertIsInstance(blob, Blob)
self.assertIs(blob.client, client)
self.assertEqual(blob.name, "b")
self.assertEqual(blob.bucket.name, "bucket_name")

nested_uri = "gs://bucket_name/path1/path2/b#name"
blob = Blob.from_string(nested_uri, client)

self.assertIsInstance(blob, Blob)
self.assertIs(blob.client, client)
self.assertEqual(blob.name, "path1/path2/b#name")
self.assertEqual(blob.bucket.name, "bucket_name")

mock_warn.assert_any_call(
_FROM_STRING_DEPRECATED,
PendingDeprecationWarning,
stacklevel=2,
)

def test_open(self):
from io import TextIOWrapper
from google.cloud.storage.fileio import BlobReader
Expand Down
30 changes: 25 additions & 5 deletions tests/unit/test_bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -4325,39 +4325,59 @@ def _generate_signed_url_helper(
}
signer.assert_called_once_with(expected_creds, **expected_kwargs)

def test_get_bucket_from_string_w_valid_uri(self):
def test_get_bucket_from_uri_w_valid_uri(self):
from google.cloud.storage.bucket import Bucket

client = self._make_client()
BUCKET_NAME = "BUCKET_NAME"
uri = "gs://" + BUCKET_NAME

bucket = Bucket.from_string(uri, client)
bucket = Bucket.from_uri(uri, client)

self.assertIsInstance(bucket, Bucket)
self.assertIs(bucket.client, client)
self.assertEqual(bucket.name, BUCKET_NAME)

def test_get_bucket_from_string_w_invalid_uri(self):
def test_get_bucket_from_uri_w_invalid_uri(self):
from google.cloud.storage.bucket import Bucket

client = self._make_client()

with pytest.raises(ValueError, match="URI scheme must be gs"):
Bucket.from_string("http://bucket_name", client)
Bucket.from_uri("http://bucket_name", client)

def test_get_bucket_from_string_w_domain_name_bucket(self):
def test_get_bucket_from_uri_w_domain_name_bucket(self):
from google.cloud.storage.bucket import Bucket

client = self._make_client()
BUCKET_NAME = "buckets.example.com"
uri = "gs://" + BUCKET_NAME

bucket = Bucket.from_uri(uri, client)

self.assertIsInstance(bucket, Bucket)
self.assertIs(bucket.client, client)
self.assertEqual(bucket.name, BUCKET_NAME)

@mock.patch("warnings.warn")
def test_get_bucket_from_string(self, mock_warn):
from google.cloud.storage.bucket import _FROM_STRING_MESSAGE
from google.cloud.storage.bucket import Bucket

client = self._make_client()
BUCKET_NAME = "BUCKET_NAME"
uri = "gs://" + BUCKET_NAME

bucket = Bucket.from_string(uri, client)

self.assertIsInstance(bucket, Bucket)
self.assertIs(bucket.client, client)
self.assertEqual(bucket.name, BUCKET_NAME)
mock_warn.assert_any_call(
_FROM_STRING_MESSAGE,
PendingDeprecationWarning,
stacklevel=2,
)

def test_generate_signed_url_no_version_passed_warning(self):
self._generate_signed_url_helper()
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1784,7 +1784,7 @@ def test_download_blob_to_file_with_uri(self):
_helpers, "_get_invocation_id", return_value=GCCL_INVOCATION_TEST_CONST
):
with mock.patch(
"google.cloud.storage.client.Blob.from_string", return_value=blob
"google.cloud.storage.client.Blob.from_uri", return_value=blob
):
client.download_blob_to_file(
"gs://bucket_name/path/to/object", file_obj
Expand Down