Skip to content

Commit 6795bef

Browse files
tseaverlandrito
authored andcommitted
Pass 'user_project' if set for Bucket API requests (googleapis#3492)
* Block 'Bucket.create' if 'user_project' set: the API does not accept that parameter.
1 parent e80c95c commit 6795bef

File tree

2 files changed

+258
-31
lines changed

2 files changed

+258
-31
lines changed

storage/google/cloud/storage/bucket.py

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,14 @@ def exists(self, client=None):
175175
:returns: True if the bucket exists in Cloud Storage.
176176
"""
177177
client = self._require_client(client)
178+
# We only need the status code (200 or not) so we seek to
179+
# minimize the returned payload.
180+
query_params = {'fields': 'name'}
181+
182+
if self.user_project is not None:
183+
query_params['userProject'] = self.user_project
184+
178185
try:
179-
# We only need the status code (200 or not) so we seek to
180-
# minimize the returned payload.
181-
query_params = {'fields': 'name'}
182186
# We intentionally pass `_target_object=None` since fields=name
183187
# would limit the local properties.
184188
client._connection.api_request(
@@ -204,6 +208,9 @@ def create(self, client=None):
204208
:param client: Optional. The client to use. If not passed, falls back
205209
to the ``client`` stored on the current bucket.
206210
"""
211+
if self.user_project is not None:
212+
raise ValueError("Cannot create bucket with 'user_project' set.")
213+
207214
client = self._require_client(client)
208215
query_params = {'project': client.project}
209216
properties = {key: self._properties[key] for key in self._changes}
@@ -264,10 +271,18 @@ def get_blob(self, blob_name, client=None):
264271
:returns: The blob object if it exists, otherwise None.
265272
"""
266273
client = self._require_client(client)
274+
query_params = {}
275+
276+
if self.user_project is not None:
277+
query_params['userProject'] = self.user_project
278+
267279
blob = Blob(bucket=self, name=blob_name)
268280
try:
269281
response = client._connection.api_request(
270-
method='GET', path=blob.path, _target_object=blob)
282+
method='GET',
283+
path=blob.path,
284+
query_params=query_params,
285+
_target_object=blob)
271286
# NOTE: We assume response.get('name') matches `blob_name`.
272287
blob._set_properties(response)
273288
# NOTE: This will not fail immediately in a batch. However, when
@@ -321,7 +336,7 @@ def list_blobs(self, max_results=None, page_token=None, prefix=None,
321336
:returns: Iterator of all :class:`~google.cloud.storage.blob.Blob`
322337
in this bucket matching the arguments.
323338
"""
324-
extra_params = {}
339+
extra_params = {'projection': projection}
325340

326341
if prefix is not None:
327342
extra_params['prefix'] = prefix
@@ -332,11 +347,12 @@ def list_blobs(self, max_results=None, page_token=None, prefix=None,
332347
if versions is not None:
333348
extra_params['versions'] = versions
334349

335-
extra_params['projection'] = projection
336-
337350
if fields is not None:
338351
extra_params['fields'] = fields
339352

353+
if self.user_project is not None:
354+
extra_params['userProject'] = self.user_project
355+
340356
client = self._require_client(client)
341357
path = self.path + '/o'
342358
iterator = HTTPIterator(
@@ -376,6 +392,11 @@ def delete(self, force=False, client=None):
376392
contains more than 256 objects / blobs.
377393
"""
378394
client = self._require_client(client)
395+
query_params = {}
396+
397+
if self.user_project is not None:
398+
query_params['userProject'] = self.user_project
399+
379400
if force:
380401
blobs = list(self.list_blobs(
381402
max_results=self._MAX_OBJECTS_FOR_ITERATION + 1,
@@ -397,7 +418,10 @@ def delete(self, force=False, client=None):
397418
# request has no response value (whether in a standard request or
398419
# in a batch request).
399420
client._connection.api_request(
400-
method='DELETE', path=self.path, _target_object=None)
421+
method='DELETE',
422+
path=self.path,
423+
query_params=query_params,
424+
_target_object=None)
401425

402426
def delete_blob(self, blob_name, client=None):
403427
"""Deletes a blob from the current bucket.
@@ -429,12 +453,20 @@ def delete_blob(self, blob_name, client=None):
429453
430454
"""
431455
client = self._require_client(client)
456+
query_params = {}
457+
458+
if self.user_project is not None:
459+
query_params['userProject'] = self.user_project
460+
432461
blob_path = Blob.path_helper(self.path, blob_name)
433462
# We intentionally pass `_target_object=None` since a DELETE
434463
# request has no response value (whether in a standard request or
435464
# in a batch request).
436465
client._connection.api_request(
437-
method='DELETE', path=blob_path, _target_object=None)
466+
method='DELETE',
467+
path=blob_path,
468+
query_params=query_params,
469+
_target_object=None)
438470

439471
def delete_blobs(self, blobs, on_error=None, client=None):
440472
"""Deletes a list of blobs from the current bucket.
@@ -497,14 +529,26 @@ def copy_blob(self, blob, destination_bucket, new_name=None,
497529
:returns: The new Blob.
498530
"""
499531
client = self._require_client(client)
532+
query_params = {}
533+
534+
if self.user_project is not None:
535+
query_params['userProject'] = self.user_project
536+
500537
if new_name is None:
501538
new_name = blob.name
539+
502540
new_blob = Blob(bucket=destination_bucket, name=new_name)
503541
api_path = blob.path + '/copyTo' + new_blob.path
504542
copy_result = client._connection.api_request(
505-
method='POST', path=api_path, _target_object=new_blob)
543+
method='POST',
544+
path=api_path,
545+
query_params=query_params,
546+
_target_object=new_blob,
547+
)
548+
506549
if not preserve_acl:
507550
new_blob.acl.save(acl={}, client=client)
551+
508552
new_blob._set_properties(copy_result)
509553
return new_blob
510554

@@ -912,9 +956,15 @@ def get_iam_policy(self, client=None):
912956
the ``getIamPolicy`` API request.
913957
"""
914958
client = self._require_client(client)
959+
query_params = {}
960+
961+
if self.user_project is not None:
962+
query_params['userProject'] = self.user_project
963+
915964
info = client._connection.api_request(
916965
method='GET',
917966
path='%s/iam' % (self.path,),
967+
query_params=query_params,
918968
_target_object=None)
919969
return Policy.from_api_repr(info)
920970

@@ -937,11 +987,17 @@ def set_iam_policy(self, policy, client=None):
937987
the ``setIamPolicy`` API request.
938988
"""
939989
client = self._require_client(client)
990+
query_params = {}
991+
992+
if self.user_project is not None:
993+
query_params['userProject'] = self.user_project
994+
940995
resource = policy.to_api_repr()
941996
resource['resourceId'] = self.path
942997
info = client._connection.api_request(
943998
method='PUT',
944999
path='%s/iam' % (self.path,),
1000+
query_params=query_params,
9451001
data=resource,
9461002
_target_object=None)
9471003
return Policy.from_api_repr(info)
@@ -965,12 +1021,16 @@ def test_iam_permissions(self, permissions, client=None):
9651021
request.
9661022
"""
9671023
client = self._require_client(client)
968-
query = {'permissions': permissions}
1024+
query_params = {'permissions': permissions}
1025+
1026+
if self.user_project is not None:
1027+
query_params['userProject'] = self.user_project
1028+
9691029
path = '%s/iam/testPermissions' % (self.path,)
9701030
resp = client._connection.api_request(
9711031
method='GET',
9721032
path=path,
973-
query_params=query)
1033+
query_params=query_params)
9741034
return resp.get('permissions', [])
9751035

9761036
def make_public(self, recursive=False, future=False, client=None):

0 commit comments

Comments
 (0)