Skip to content

Commit

Permalink
Pass 'user_project' if set for Blob API requests (#3495)
Browse files Browse the repository at this point in the history
  • Loading branch information
tseaver committed Oct 10, 2017
1 parent 8b3456c commit ac0c769
Show file tree
Hide file tree
Showing 2 changed files with 284 additions and 63 deletions.
83 changes: 70 additions & 13 deletions storage/google/cloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,14 @@ def exists(self, client=None):
:returns: True if the blob exists in Cloud Storage.
"""
client = self._require_client(client)
# We only need the status code (200 or not) so we seek to
# minimize the returned payload.
query_params = {'fields': 'name'}

if self.user_project is not None:
query_params['userProject'] = self.user_project

try:
# We only need the status code (200 or not) so we seek to
# minimize the returned payload.
query_params = {'fields': 'name'}
# We intentionally pass `_target_object=None` since fields=name
# would limit the local properties.
client._connection.api_request(
Expand Down Expand Up @@ -399,6 +403,8 @@ def _get_download_url(self):
download_url = _DOWNLOAD_URL_TEMPLATE.format(path=self.path)
if self.generation is not None:
download_url += u'&generation={:d}'.format(self.generation)
if self.user_project is not None:
download_url += u'&userProject={}'.format(self.user_project)
return download_url
else:
return self.media_link
Expand Down Expand Up @@ -649,6 +655,10 @@ def _do_multipart_upload(self, client, stream, content_type,

upload_url = _MULTIPART_URL_TEMPLATE.format(
bucket_path=self.bucket.path)

if self.user_project is not None:
upload_url += '&userProject={}'.format(self.user_project)

upload = MultipartUpload(upload_url, headers=headers)

if num_retries is not None:
Expand Down Expand Up @@ -721,6 +731,10 @@ def _initiate_resumable_upload(self, client, stream, content_type,

upload_url = _RESUMABLE_URL_TEMPLATE.format(
bucket_path=self.bucket.path)

if self.user_project is not None:
upload_url += '&userProject={}'.format(self.user_project)

upload = ResumableUpload(upload_url, chunk_size, headers=headers)

if num_retries is not None:
Expand Down Expand Up @@ -1074,9 +1088,16 @@ def get_iam_policy(self, client=None):
the ``getIamPolicy`` API request.
"""
client = self._require_client(client)

query_params = {}

if self.user_project is not None:
query_params['userProject'] = self.user_project

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

Expand All @@ -1099,11 +1120,18 @@ def set_iam_policy(self, policy, client=None):
the ``setIamPolicy`` API request.
"""
client = self._require_client(client)

query_params = {}

if self.user_project is not None:
query_params['userProject'] = self.user_project

resource = policy.to_api_repr()
resource['resourceId'] = self.path
info = client._connection.api_request(
method='PUT',
path='%s/iam' % (self.path,),
query_params=query_params,
data=resource,
_target_object=None)
return Policy.from_api_repr(info)
Expand All @@ -1127,12 +1155,17 @@ def test_iam_permissions(self, permissions, client=None):
request.
"""
client = self._require_client(client)
query = {'permissions': permissions}
query_params = {'permissions': permissions}

if self.user_project is not None:
query_params['userProject'] = self.user_project

path = '%s/iam/testPermissions' % (self.path,)
resp = client._connection.api_request(
method='GET',
path=path,
query_params=query)
query_params=query_params)

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

def make_public(self, client=None):
Expand Down Expand Up @@ -1162,13 +1195,22 @@ def compose(self, sources, client=None):
"""
if self.content_type is None:
raise ValueError("Destination 'content_type' not set.")

client = self._require_client(client)
query_params = {}

if self.user_project is not None:
query_params['userProject'] = self.user_project

request = {
'sourceObjects': [{'name': source.name} for source in sources],
'destination': self._properties.copy(),
}
api_response = client._connection.api_request(
method='POST', path=self.path + '/compose', data=request,
method='POST',
path=self.path + '/compose',
query_params=query_params,
data=request,
_target_object=self)
self._set_properties(api_response)

Expand Down Expand Up @@ -1200,14 +1242,20 @@ def rewrite(self, source, token=None, client=None):
headers.update(_get_encryption_headers(
source._encryption_key, source=True))

query_params = {}

if token:
query_params = {'rewriteToken': token}
else:
query_params = {}
query_params['rewriteToken'] = token

if self.user_project is not None:
query_params['userProject'] = self.user_project

api_response = client._connection.api_request(
method='POST', path=source.path + '/rewriteTo' + self.path,
query_params=query_params, data=self._properties, headers=headers,
method='POST',
path=source.path + '/rewriteTo' + self.path,
query_params=query_params,
data=self._properties,
headers=headers,
_target_object=self)
rewritten = int(api_response['totalBytesRewritten'])
size = int(api_response['objectSize'])
Expand Down Expand Up @@ -1238,13 +1286,22 @@ def update_storage_class(self, new_class, client=None):
raise ValueError("Invalid storage class: %s" % (new_class,))

client = self._require_client(client)

query_params = {}

if self.user_project is not None:
query_params['userProject'] = self.user_project

headers = _get_encryption_headers(self._encryption_key)
headers.update(_get_encryption_headers(
self._encryption_key, source=True))

api_response = client._connection.api_request(
method='POST', path=self.path + '/rewriteTo' + self.path,
data={'storageClass': new_class}, headers=headers,
method='POST',
path=self.path + '/rewriteTo' + self.path,
query_params=query_params,
data={'storageClass': new_class},
headers=headers,
_target_object=self)
self._set_properties(api_response['resource'])

Expand Down
Loading

0 comments on commit ac0c769

Please sign in to comment.