Skip to content

Commit

Permalink
refactor: use 'Client._patch_resource' in 'Blob.make_public'
Browse files Browse the repository at this point in the history
Indirecly, via 'ACL.save'.

Also, adds 'timeout' and 'retry' support to 'Blob.make_public'.

Toward #38.
  • Loading branch information
tseaver committed May 8, 2021
1 parent cffaa60 commit 83201db
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 14 deletions.
28 changes: 26 additions & 2 deletions google/cloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -2978,16 +2978,40 @@ def test_iam_permissions(

return resp.get("permissions", [])

def make_public(self, client=None):
def make_public(
self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY,
):
"""Update blob's ACL, granting read access to anonymous users.
:type client: :class:`~google.cloud.storage.client.Client` or
``NoneType``
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the blob's bucket.
:type timeout: float or tuple
:param timeout: (Optional) The amount of time, in seconds, to wait
for the server response. The timeout applies to each underlying
request.
Can also be passed as a tuple (connect_timeout, read_timeout).
See :meth:`requests.Session.request` documentation for details.
:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
:param retry: (Optional) How to retry the RPC. A None value will disable retries.
A google.api_core.retry.Retry value will enable retries, and the object will
define retriable response codes and errors and configure backoff and timeout options.
A google.cloud.storage.retry.ConditionalRetryPolicy value wraps a Retry object and
activates it only if certain conditions are met. This class exists to provide safe defaults
for RPC calls that are not technically safe to retry normally (due to potential data
duplication or other side-effects) but become safe to retry if a condition such as
if_metageneration_match is set.
See the retry.py source code and docstrings in this package (google.cloud.storage.retry) for
information on retry types and how to configure them.
"""
self.acl.all().grant_read()
self.acl.save(client=client)
self.acl.save(client=client, timeout=timeout, retry=retry)

def make_private(self, client=None):
"""Update blob's ACL, revoking read access for anonymous users.
Expand Down
58 changes: 46 additions & 12 deletions tests/unit/test_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -3418,25 +3418,59 @@ def test_test_iam_permissions_w_user_project_w_timeout_w_retry(self):
_target_object=None,
)

def test_make_public(self):
def test_make_public_w_defaults(self):
from google.cloud.storage.acl import _ACLEntity

BLOB_NAME = "blob-name"
blob_name = "blob-name"
permissive = [{"entity": "allUsers", "role": _ACLEntity.READER_ROLE}]
after = ({"status": http_client.OK}, {"acl": permissive})
connection = _Connection(after)
client = _Client(connection)
api_response = {"acl": permissive}
client = mock.Mock(spec=["_patch_resource"])
client._patch_resource.return_value = api_response
bucket = _Bucket(client=client)
blob = self._make_one(BLOB_NAME, bucket=bucket)
blob = self._make_one(blob_name, bucket=bucket)
blob.acl.loaded = True

blob.make_public()

self.assertEqual(list(blob.acl), permissive)
kw = connection._requested
self.assertEqual(len(kw), 1)
self.assertEqual(kw[0]["method"], "PATCH")
self.assertEqual(kw[0]["path"], "/b/name/o/%s" % BLOB_NAME)
self.assertEqual(kw[0]["data"], {"acl": permissive})
self.assertEqual(kw[0]["query_params"], {"projection": "full"})

expected_patch_data = {"acl": permissive}
expected_query_params = {"projection": "full"}
client._patch_resource.assert_called_once_with(
blob.path,
expected_patch_data,
query_params=expected_query_params,
timeout=self._get_default_timeout(),
retry=DEFAULT_RETRY,
)

def test_make_public_w_timeout_w_retry(self):
from google.cloud.storage.acl import _ACLEntity

blob_name = "blob-name"
permissive = [{"entity": "allUsers", "role": _ACLEntity.READER_ROLE}]
api_response = {"acl": permissive}
client = mock.Mock(spec=["_patch_resource"])
client._patch_resource.return_value = api_response
bucket = _Bucket(client=client)
blob = self._make_one(blob_name, bucket=bucket)
blob.acl.loaded = True
timeout = 42
retry = mock.Mock(spec=[])

blob.make_public(timeout=timeout, retry=retry)

self.assertEqual(list(blob.acl), permissive)

expected_patch_data = {"acl": permissive}
expected_query_params = {"projection": "full"}
client._patch_resource.assert_called_once_with(
blob.path,
expected_patch_data,
query_params=expected_query_params,
timeout=timeout,
retry=retry,
)

def test_make_private(self):
BLOB_NAME = "blob-name"
Expand Down

0 comments on commit 83201db

Please sign in to comment.