Skip to content

Commit

Permalink
refactor: add / use 'Client._post_resource' method (#443)
Browse files Browse the repository at this point in the history
Toward #38.
  • Loading branch information
tseaver committed Jun 8, 2021
1 parent 94fd0ca commit ef764ac
Show file tree
Hide file tree
Showing 8 changed files with 1,400 additions and 1,236 deletions.
19 changes: 9 additions & 10 deletions google/cloud/storage/blob.py
Expand Up @@ -3164,14 +3164,13 @@ def compose(
"sourceObjects": source_objects,
"destination": self._properties.copy(),
}
api_response = client._connection.api_request(
method="POST",
path=self.path + "/compose",
api_response = client._post_resource(
"{}/compose".format(self.path),
request,
query_params=query_params,
data=request,
_target_object=self,
timeout=timeout,
retry=retry,
_target_object=self,
)
self._set_properties(api_response)

Expand Down Expand Up @@ -3315,15 +3314,15 @@ def rewrite(
if_source_metageneration_not_match=if_source_metageneration_not_match,
)

api_response = client._connection.api_request(
method="POST",
path=source.path + "/rewriteTo" + self.path,
path = "{}/rewriteTo{}".format(source.path, self.path)
api_response = client._post_resource(
path,
self._properties,
query_params=query_params,
data=self._properties,
headers=headers,
_target_object=self,
timeout=timeout,
retry=retry,
_target_object=self,
)
rewritten = int(api_response["totalBytesRewritten"])
size = int(api_response["objectSize"])
Expand Down
34 changes: 17 additions & 17 deletions google/cloud/storage/bucket.py
Expand Up @@ -1986,13 +1986,13 @@ def copy_blob(

new_blob = Blob(bucket=destination_bucket, name=new_name)
api_path = blob.path + "/copyTo" + new_blob.path
copy_result = client._connection.api_request(
method="POST",
path=api_path,
copy_result = client._post_resource(
api_path,
None,
query_params=query_params,
_target_object=new_blob,
timeout=timeout,
retry=retry,
_target_object=new_blob,
)

if not preserve_acl:
Expand All @@ -2006,7 +2006,6 @@ def rename_blob(
blob,
new_name,
client=None,
timeout=_DEFAULT_TIMEOUT,
if_generation_match=None,
if_generation_not_match=None,
if_metageneration_match=None,
Expand All @@ -2015,6 +2014,7 @@ def rename_blob(
if_source_generation_not_match=None,
if_source_metageneration_match=None,
if_source_metageneration_not_match=None,
timeout=_DEFAULT_TIMEOUT,
retry=DEFAULT_RETRY_IF_GENERATION_SPECIFIED,
):
"""Rename the given blob using copy and delete operations.
Expand Down Expand Up @@ -2044,14 +2044,6 @@ def rename_blob(
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the current 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 individual
request.
Can also be passed as a tuple (connect_timeout, read_timeout).
See :meth:`requests.Session.request` documentation for details.
:type if_generation_match: long
:param if_generation_match: (Optional) Makes the operation
conditional on whether the destination
Expand Down Expand Up @@ -2113,6 +2105,14 @@ def rename_blob(
does not match the given value.
Also used in the delete request.
: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 individual
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
Expand Down Expand Up @@ -3311,13 +3311,13 @@ def lock_retention_policy(
query_params["userProject"] = self.user_project

path = "/b/{}/lockRetentionPolicy".format(self.name)
api_response = client._connection.api_request(
method="POST",
path=path,
api_response = client._post_resource(
path,
None,
query_params=query_params,
_target_object=self,
timeout=timeout,
retry=retry,
_target_object=self,
)
self._set_properties(api_response)

Expand Down
103 changes: 92 additions & 11 deletions google/cloud/storage/client.py
Expand Up @@ -528,6 +528,77 @@ def _put_resource(
_target_object=_target_object,
)

def _post_resource(
self,
path,
data,
query_params=None,
headers=None,
timeout=_DEFAULT_TIMEOUT,
retry=None,
_target_object=None,
):
"""Helper for bucket / blob methods making API 'POST' calls.
Args:
path str:
The path of the resource to which to post.
data dict:
The data to be posted.
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 returned from the post.
Raises:
google.cloud.exceptions.NotFound
If the bucket is not found.
"""
return self._connection.api_request(
method="POST",
path=path,
data=data,
query_params=query_params,
headers=headers,
timeout=timeout,
retry=retry,
_target_object=_target_object,
)

def _delete_resource(
self,
path,
Expand Down Expand Up @@ -875,14 +946,13 @@ def create_bucket(
if location is not None:
properties["location"] = location

api_response = self._connection.api_request(
method="POST",
path="/b",
api_response = self._post_resource(
"/b",
properties,
query_params=query_params,
data=properties,
_target_object=bucket,
timeout=timeout,
retry=retry,
_target_object=bucket,
)

bucket._set_properties(api_response)
Expand Down Expand Up @@ -1278,6 +1348,7 @@ def create_hmac_key(
project_id=None,
user_project=None,
timeout=_DEFAULT_TIMEOUT,
retry=None,
):
"""Create an HMAC key for a service account.
Expand All @@ -1298,6 +1369,20 @@ def create_hmac_key(
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.
:rtype:
Tuple[:class:`~google.cloud.storage.hmac_key.HMACKeyMetadata`, str]
:returns: metadata for the created key, plus the bytes of the key's secret, which is an 40-character base64-encoded string.
Expand All @@ -1311,12 +1396,8 @@ def create_hmac_key(
if user_project is not None:
qs_params["userProject"] = user_project

api_response = self._connection.api_request(
method="POST",
path=path,
query_params=qs_params,
timeout=timeout,
retry=None,
api_response = self._post_resource(
path, None, query_params=qs_params, timeout=timeout, retry=retry,
)
metadata = HMACKeyMetadata(self)
metadata._properties = api_response["metadata"]
Expand Down
25 changes: 17 additions & 8 deletions google/cloud/storage/notification.py
Expand Up @@ -233,7 +233,7 @@ def _set_properties(self, response):
self._properties.clear()
self._properties.update(response)

def create(self, client=None, timeout=_DEFAULT_TIMEOUT):
def create(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=None):
"""API wrapper: create the notification.
See:
Expand All @@ -251,6 +251,20 @@ def create(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: 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.
"""
if self.notification_id is not None:
raise ValueError(
Expand All @@ -266,13 +280,8 @@ def create(self, client=None, timeout=_DEFAULT_TIMEOUT):
path = "/b/{}/notificationConfigs".format(self.bucket.name)
properties = self._properties.copy()
properties["topic"] = _TOPIC_REF_FMT.format(self.topic_project, self.topic_name)
self._properties = client._connection.api_request(
method="POST",
path=path,
query_params=query_params,
data=properties,
timeout=timeout,
retry=None,
self._properties = client._post_resource(
path, properties, query_params=query_params, timeout=timeout, retry=retry,
)

def exists(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=DEFAULT_RETRY):
Expand Down

0 comments on commit ef764ac

Please sign in to comment.