Skip to content

Commit 7104f2a

Browse files
Gurov Ilyacojenco
Gurov Ilya
authored andcommitted
feat: add Bucket.reload() and Bucket.update() wrappers to restrict generation match args (googleapis#153)
Towards googleapis#127
1 parent c142dd0 commit 7104f2a

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

google/cloud/storage/bucket.py

+85
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,91 @@ def create(
783783
timeout=timeout,
784784
)
785785

786+
def update(
787+
self,
788+
client=None,
789+
timeout=_DEFAULT_TIMEOUT,
790+
if_metageneration_match=None,
791+
if_metageneration_not_match=None,
792+
):
793+
"""Sends all properties in a PUT request.
794+
795+
Updates the ``_properties`` with the response from the backend.
796+
797+
If :attr:`user_project` is set, bills the API request to that project.
798+
799+
:type client: :class:`~google.cloud.storage.client.Client` or
800+
``NoneType``
801+
:param client: the client to use. If not passed, falls back to the
802+
``client`` stored on the current object.
803+
804+
:type timeout: float or tuple
805+
:param timeout: (Optional) The amount of time, in seconds, to wait
806+
for the server response.
807+
808+
Can also be passed as a tuple (connect_timeout, read_timeout).
809+
See :meth:`requests.Session.request` documentation for details.
810+
811+
:type if_metageneration_match: long
812+
:param if_metageneration_match: (Optional) Make the operation conditional on whether the
813+
blob's current metageneration matches the given value.
814+
815+
:type if_metageneration_not_match: long
816+
:param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
817+
blob's current metageneration does not match the given value.
818+
"""
819+
super(Bucket, self).update(
820+
client=client,
821+
timeout=timeout,
822+
if_metageneration_match=if_metageneration_match,
823+
if_metageneration_not_match=if_metageneration_not_match,
824+
)
825+
826+
def reload(
827+
self,
828+
client=None,
829+
projection="noAcl",
830+
timeout=_DEFAULT_TIMEOUT,
831+
if_metageneration_match=None,
832+
if_metageneration_not_match=None,
833+
):
834+
"""Reload properties from Cloud Storage.
835+
836+
If :attr:`user_project` is set, bills the API request to that project.
837+
838+
:type client: :class:`~google.cloud.storage.client.Client` or
839+
``NoneType``
840+
:param client: the client to use. If not passed, falls back to the
841+
``client`` stored on the current object.
842+
843+
:type projection: str
844+
:param projection: (Optional) If used, must be 'full' or 'noAcl'.
845+
Defaults to ``'noAcl'``. Specifies the set of
846+
properties to return.
847+
848+
:type timeout: float or tuple
849+
:param timeout: (Optional) The amount of time, in seconds, to wait
850+
for the server response.
851+
852+
Can also be passed as a tuple (connect_timeout, read_timeout).
853+
See :meth:`requests.Session.request` documentation for details.
854+
855+
:type if_metageneration_match: long
856+
:param if_metageneration_match: (Optional) Make the operation conditional on whether the
857+
blob's current metageneration matches the given value.
858+
859+
:type if_metageneration_not_match: long
860+
:param if_metageneration_not_match: (Optional) Make the operation conditional on whether the
861+
blob's current metageneration does not match the given value.
862+
"""
863+
super(Bucket, self).reload(
864+
client=client,
865+
projection=projection,
866+
timeout=timeout,
867+
if_metageneration_match=if_metageneration_match,
868+
if_metageneration_not_match=if_metageneration_not_match,
869+
)
870+
786871
def patch(
787872
self,
788873
client=None,

tests/unit/test_bucket.py

+56
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,62 @@ def test_delete_blobs_miss_w_on_error(self):
11841184
self.assertEqual(kw[1]["path"], "/b/%s/o/%s" % (NAME, NONESUCH))
11851185
self.assertEqual(kw[1]["timeout"], self._get_default_timeout())
11861186

1187+
def test_reload_bucket_w_metageneration_match(self):
1188+
NAME = "name"
1189+
METAGENERATION_NUMBER = 9
1190+
1191+
connection = _Connection({})
1192+
client = _Client(connection)
1193+
bucket = self._make_one(client=client, name=NAME)
1194+
1195+
bucket.reload(if_metageneration_match=METAGENERATION_NUMBER)
1196+
1197+
self.assertEqual(len(connection._requested), 1)
1198+
req = connection._requested[0]
1199+
self.assertEqual(req["method"], "GET")
1200+
self.assertEqual(req["path"], "/b/%s" % NAME)
1201+
self.assertEqual(req["timeout"], self._get_default_timeout())
1202+
self.assertEqual(
1203+
req["query_params"],
1204+
{"projection": "noAcl", "ifMetagenerationMatch": METAGENERATION_NUMBER},
1205+
)
1206+
1207+
def test_reload_bucket_w_generation_match(self):
1208+
connection = _Connection({})
1209+
client = _Client(connection)
1210+
bucket = self._make_one(client=client, name="name")
1211+
1212+
with self.assertRaises(TypeError):
1213+
bucket.reload(if_generation_match=6)
1214+
1215+
def test_update_bucket_w_metageneration_match(self):
1216+
NAME = "name"
1217+
METAGENERATION_NUMBER = 9
1218+
1219+
connection = _Connection({})
1220+
client = _Client(connection)
1221+
bucket = self._make_one(client=client, name=NAME)
1222+
1223+
bucket.update(if_metageneration_match=METAGENERATION_NUMBER)
1224+
1225+
self.assertEqual(len(connection._requested), 1)
1226+
req = connection._requested[0]
1227+
self.assertEqual(req["method"], "PUT")
1228+
self.assertEqual(req["path"], "/b/%s" % NAME)
1229+
self.assertEqual(req["timeout"], self._get_default_timeout())
1230+
self.assertEqual(
1231+
req["query_params"],
1232+
{"projection": "full", "ifMetagenerationMatch": METAGENERATION_NUMBER},
1233+
)
1234+
1235+
def test_update_bucket_w_generation_match(self):
1236+
connection = _Connection({})
1237+
client = _Client(connection)
1238+
bucket = self._make_one(client=client, name="name")
1239+
1240+
with self.assertRaises(TypeError):
1241+
bucket.update(if_generation_match=6)
1242+
11871243
@staticmethod
11881244
def _make_blob(bucket_name, blob_name):
11891245
from google.cloud.storage.blob import Blob

0 commit comments

Comments
 (0)