Skip to content
This repository was archived by the owner on Mar 31, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
7 changes: 3 additions & 4 deletions google/cloud/storage/_helpers.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -215,14 +215,13 @@ def reload(
if_metageneration_match=if_metageneration_match,
if_metageneration_not_match=if_metageneration_not_match,
)
api_response = client._connection.api_request(
method="GET",
path=self.path,
api_response = client._get_resource(
self.path,
query_params=query_params,
headers=self._encryption_headers(),
_target_object=self,
timeout=timeout,
retry=retry,
_target_object=self,
)
self._set_properties(api_response)

Expand Down
18 changes: 15 additions & 3 deletions google/cloud/storage/acl.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,6 +85,7 @@
"""

from google.cloud.storage.constants import _DEFAULT_TIMEOUT
from google.cloud.storage.retry import DEFAULT_RETRY


class _ACLEntity(object):
Expand DownExpand Up@@ -206,6 +207,7 @@ class ACL(object):

# Subclasses must override to provide these attributes (typically,
# as properties).
client = None
reload_path = None
save_path = None
user_project = None
Expand DownExpand Up@@ -430,7 +432,7 @@ def _require_client(self, client):
client = self.client
return client

def reload(self, client=None, timeout=_DEFAULT_TIMEOUT):
def reload(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
"""Reload the ACL data from Cloud Storage.

If :attr:`user_project` is set, bills the API request to that project.
Expand All@@ -445,6 +447,15 @@ def reload(self, client=None, timeout=_DEFAULT_TIMEOUT):

Can also be passed as a tuple (connect_timeout, read_timeout).
See :meth:`requests.Session.request` documentation for details.

:type retry: :class:`~google.api_core.retry.Retry`
: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.
"""
path = self.reload_path
client = self._require_client(client)
Expand All@@ -455,10 +466,11 @@ def reload(self, client=None, timeout=_DEFAULT_TIMEOUT):

self.entities.clear()

found = client._connection.api_request(
method="GET", path=path, query_params=query_params, timeout=timeout,
found = client._get_resource(
path, query_params=query_params, timeout=timeout, retry=retry,
)
self.loaded = True

for entry in found.get("items", ()):
self.add_entity(self.entity_from_dict(entry))

Expand Down
24 changes: 11 additions & 13 deletions google/cloud/storage/blob.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -704,20 +704,19 @@ def exists(
try:
# We intentionally pass `_target_object=None` since fields=name
# would limit the local properties.
client._connection.api_request(
method="GET",
path=self.path,
client._get_resource(
self.path,
query_params=query_params,
_target_object=None,
timeout=timeout,
retry=retry,
_target_object=None,
)
except NotFound:
# NOTE: This will not fail immediately in a batch. However, when
# Batch.finish() is called, the resulting `NotFound` will be
# raised.
return True
except NotFound:
return False
return True

def delete(
self,
Expand DownExpand Up@@ -2829,13 +2828,12 @@ def get_iam_policy(
if requested_policy_version is not None:
query_params["optionsRequestedPolicyVersion"] = requested_policy_version

info = client._connection.api_request(
method="GET",
path="%s/iam" % (self.path,),
info = client._get_resource(
"%s/iam" % (self.path,),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more of just a style thing, but in modern Python, should we be preferring str.format or f strings if Python 2 support has been dropped?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we drop Python2, I would definitely prefer f-strings.

query_params=query_params,
_target_object=None,
timeout=timeout,
retry=retry,
_target_object=None,
)
return Policy.from_api_repr(info)

Expand DownExpand Up@@ -2970,12 +2968,12 @@ def test_iam_permissions(
query_params["userProject"] = self.user_project

path = "%s/iam/testPermissions" % (self.path,)
resp = client._connection.api_request(
method="GET",
path=path,
resp = client._get_resource(
path,
query_params=query_params,
timeout=timeout,
retry=retry,
_target_object=None,
)

return resp.get("permissions", [])
Expand Down
24 changes: 11 additions & 13 deletions google/cloud/storage/bucket.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -786,20 +786,19 @@ def exists(
try:
# We intentionally pass `_target_object=None` since fields=name
# would limit the local properties.
client._connection.api_request(
method="GET",
path=self.path,
client._get_resource(
self.path,
query_params=query_params,
_target_object=None,
timeout=timeout,
retry=retry,
_target_object=None,
)
except NotFound:
# NOTE: This will not fail immediately in a batch. However, when
# Batch.finish() is called, the resulting `NotFound` will be
# raised.
return True
except NotFound:
return False
return True

def create(
self,
Expand DownExpand Up@@ -2882,13 +2881,12 @@ def get_iam_policy(
if requested_policy_version is not None:
query_params["optionsRequestedPolicyVersion"] = requested_policy_version

info = client._connection.api_request(
method="GET",
path="%s/iam" % (self.path,),
info = client._get_resource(
"%s/iam" % (self.path,),
query_params=query_params,
_target_object=None,
timeout=timeout,
retry=retry,
_target_object=None,
)
return Policy.from_api_repr(info)

Expand DownExpand Up@@ -3008,12 +3006,12 @@ def test_iam_permissions(
query_params["userProject"] = self.user_project

path = "%s/iam/testPermissions" % (self.path,)
resp = client._connection.api_request(
method="GET",
path=path,
resp = client._get_resource(
path,
query_params=query_params,
timeout=timeout,
retry=retry,
_target_object=None,
)
return resp.get("permissions", [])

Expand Down
71 changes: 68 additions & 3 deletions google/cloud/storage/client.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -284,10 +284,9 @@ def get_service_account_email(
"""
if project is None:
project = self.project

path = "/projects/%s/serviceAccount" % (project,)
api_response = self._base_connection.api_request(
method="GET", path=path, timeout=timeout, retry=retry,
)
api_response = self._get_resource(path, timeout=timeout, retry=retry)
return api_response["email_address"]

def bucket(self, bucket_name, user_project=None):
Expand DownExpand Up@@ -321,6 +320,72 @@ def batch(self):
"""
return Batch(client=self)

def _get_resource(
self,
path,
query_params=None,
headers=None,
timeout=_DEFAULT_TIMEOUT,
retry=DEFAULT_RETRY,
_target_object=None,
):
"""Helper for bucket / blob methods making API 'GET' calls.

Args:
path str:
The path of the resource to fetch.

query_params Optional[dict]:
HTTP query parameters to be passed

headers Optional[dict]:
HTTP headers to be passed

timeout (Optional[Union[float, Tuple[float, float]]]):
The amount of time, in seconds, to wait for the server response.

Can also be passed as a tuple (connect_timeout, read_timeout).
See :meth:`requests.Session.request` documentation for details.

retry (Optional[Union[google.api_core.retry.Retry, google.cloud.storage.retry.ConditionalRetryPolicy]]):
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.

_target_object (Union[ \
:class:`~google.cloud.storage.bucket.Bucket`, \
:class:`~google.cloud.storage.bucket.blob`, \
]):
Object to which future data is to be applied -- only relevant
in the context of a batch.

Returns:
dict
The JSON resource fetched

Raises:
google.cloud.exceptions.NotFound
If the bucket is not found.
"""
return self._connection.api_request(
method="GET",
path=path,
query_params=query_params,
headers=headers,
timeout=timeout,
retry=retry,
_target_object=_target_object,
)

def get_bucket(
self,
bucket_or_name,
Expand Down
16 changes: 4 additions & 12 deletions google/cloud/storage/hmac_key.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -222,12 +222,8 @@ def exists(self, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
if self.user_project is not None:
qs_params["userProject"] = self.user_project

self._client._connection.api_request(
method="GET",
path=self.path,
query_params=qs_params,
timeout=timeout,
retry=retry,
self._client._get_resource(
self.path, query_params=qs_params, timeout=timeout, retry=retry,
)
except NotFound:
return False
Expand DownExpand Up@@ -266,12 +262,8 @@ def reload(self, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
if self.user_project is not None:
qs_params["userProject"] = self.user_project

self._properties = self._client._connection.api_request(
method="GET",
path=self.path,
query_params=qs_params,
timeout=timeout,
retry=retry,
self._properties = self._client._get_resource(
self.path, query_params=qs_params, timeout=timeout, retry=retry,
)

def update(self, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY_IF_ETAG_IN_JSON):
Expand Down
16 changes: 4 additions & 12 deletions google/cloud/storage/notification.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -323,12 +323,8 @@ def exists(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
query_params["userProject"] = self.bucket.user_project

try:
client._connection.api_request(
method="GET",
path=self.path,
query_params=query_params,
timeout=timeout,
retry=retry,
client._get_resource(
self.path, query_params=query_params, timeout=timeout, retry=retry,
)
except NotFound:
return False
Expand DownExpand Up@@ -381,12 +377,8 @@ def reload(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
if self.bucket.user_project is not None:
query_params["userProject"] = self.bucket.user_project

response = client._connection.api_request(
method="GET",
path=self.path,
query_params=query_params,
timeout=timeout,
retry=retry,
response = client._get_resource(
self.path, query_params=query_params, timeout=timeout, retry=retry,
)
self._set_properties(response)

Expand Down
Loading