Skip to content

Commit

Permalink
Storage: Implement predefined acl
Browse files Browse the repository at this point in the history
  • Loading branch information
chemelnucfin committed Jan 17, 2018
1 parent 95aaa50 commit a3c3774
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 29 deletions.
65 changes: 51 additions & 14 deletions storage/google/cloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ def _get_upload_arguments(self, content_type):
return headers, object_metadata, content_type

def _do_multipart_upload(self, client, stream, content_type,
size, num_retries):
size, num_retries, predefined_acl):
"""Perform a multipart upload.
Assumes ``chunk_size`` is :data:`None` on the current blob.
Expand Down Expand Up @@ -664,6 +664,9 @@ def _do_multipart_upload(self, client, stream, content_type,
:param num_retries: Number of upload retries. (Deprecated: This
argument will be removed in a future release.)
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
:rtype: :class:`~requests.Response`
:returns: The "200 OK" response object returned after the multipart
upload request.
Expand All @@ -688,6 +691,9 @@ def _do_multipart_upload(self, client, stream, content_type,

if self.user_project is not None:
name_value_pairs.append(('userProject', self.user_project))
if predefined_acl is not None:
self._acl.save_predefined(predefined_acl)
name_value_pairs.append(('predefinedAcl', predefined_acl))

upload_url = _add_query_parameters(base_url, name_value_pairs)
upload = MultipartUpload(upload_url, headers=headers)
Expand All @@ -703,7 +709,7 @@ def _do_multipart_upload(self, client, stream, content_type,

def _initiate_resumable_upload(self, client, stream, content_type,
size, num_retries, extra_headers=None,
chunk_size=None):
chunk_size=None, predefined_acl=None):
"""Initiate a resumable upload.
The content type of the upload will be determined in order
Expand Down Expand Up @@ -743,6 +749,9 @@ def _initiate_resumable_upload(self, client, stream, content_type,
If not passed, will fall back to the chunk size on the
current blob.
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
:rtype: tuple
:returns:
Pair of
Expand All @@ -766,6 +775,9 @@ def _initiate_resumable_upload(self, client, stream, content_type,

if self.user_project is not None:
name_value_pairs.append(('userProject', self.user_project))
if predefined_acl is not None:
self._acl.save_predefined(predefined_acl)
name_value_pairs.append(('predefinedAcl', predefined_acl))

upload_url = _add_query_parameters(base_url, name_value_pairs)
upload = ResumableUpload(upload_url, chunk_size, headers=headers)
Expand All @@ -781,7 +793,7 @@ def _initiate_resumable_upload(self, client, stream, content_type,
return upload, transport

def _do_resumable_upload(self, client, stream, content_type,
size, num_retries):
size, num_retries, predefined_acl=None):
"""Perform a resumable upload.
Assumes ``chunk_size`` is not :data:`None` on the current blob.
Expand Down Expand Up @@ -812,19 +824,24 @@ def _do_resumable_upload(self, client, stream, content_type,
:param num_retries: Number of upload retries. (Deprecated: This
argument will be removed in a future release.)
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
:rtype: :class:`~requests.Response`
:returns: The "200 OK" response object returned after the final chunk
is uploaded.
"""
upload, transport = self._initiate_resumable_upload(
client, stream, content_type, size, num_retries)
client, stream, content_type, size, num_retries,
predefined_acl=predefined_acl)

while not upload.finished:
response = upload.transmit_next_chunk(transport)

return response

def _do_upload(self, client, stream, content_type, size, num_retries):
def _do_upload(self, client, stream, content_type, size, num_retries,
predefined_acl):
"""Determine an upload strategy and then perform the upload.
If the current blob has a ``chunk_size`` set, then a resumable upload
Expand Down Expand Up @@ -857,22 +874,28 @@ def _do_upload(self, client, stream, content_type, size, num_retries):
:param num_retries: Number of upload retries. (Deprecated: This
argument will be removed in a future release.)
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
:rtype: dict
:returns: The parsed JSON from the "200 OK" response. This will be the
**only** response in the multipart case and it will be the
**final** response in the resumable case.
"""
if self.chunk_size is None:
response = self._do_multipart_upload(
client, stream, content_type, size, num_retries)
client, stream, content_type, size, num_retries,
predefined_acl)
else:
response = self._do_resumable_upload(
client, stream, content_type, size, num_retries)
client, stream, content_type, size, num_retries,
predefined_acl)

return response.json()

def upload_from_file(self, file_obj, rewind=False, size=None,
content_type=None, num_retries=None, client=None):
content_type=None, num_retries=None, client=None,
predefined_acl=None):
"""Upload the contents of this blob from a file-like object.
The content type of the upload will be determined in order
Expand Down Expand Up @@ -920,12 +943,15 @@ def upload_from_file(self, file_obj, rewind=False, size=None,
concluded once ``file_obj`` is exhausted.
:type content_type: str
:param content_type: Optional type of content being uploaded.
:param content_type: (Optional) type of content being uploaded.
:type num_retries: int
:param num_retries: Number of upload retries. (Deprecated: This
argument will be removed in a future release.)
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
:type client: :class:`~google.cloud.storage.client.Client`
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the blob's bucket.
Expand All @@ -943,12 +969,14 @@ def upload_from_file(self, file_obj, rewind=False, size=None,
_maybe_rewind(file_obj, rewind=rewind)
try:
created_json = self._do_upload(
client, file_obj, content_type, size, num_retries)
client, file_obj, content_type, size, num_retries,
predefined_acl)
self._set_properties(created_json)
except resumable_media.InvalidResponse as exc:
_raise_from_invalid_response(exc)

def upload_from_filename(self, filename, content_type=None, client=None):
def upload_from_filename(self, filename, content_type=None, client=None,
predefined_acl=None):
"""Upload this blob's contents from the content of a named file.
The content type of the upload will be determined in order
Expand Down Expand Up @@ -982,16 +1010,20 @@ def upload_from_filename(self, filename, content_type=None, client=None):
:type client: :class:`~google.cloud.storage.client.Client`
:param client: (Optional) The client to use. If not passed, falls back
to the ``client`` stored on the blob's bucket.
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
"""
content_type = self._get_content_type(content_type, filename=filename)

with open(filename, 'rb') as file_obj:
total_bytes = os.fstat(file_obj.fileno()).st_size
self.upload_from_file(
file_obj, content_type=content_type, client=client,
size=total_bytes)
size=total_bytes, predefined_acl=predefined_acl)

def upload_from_string(self, data, content_type='text/plain', client=None):
def upload_from_string(self, data, content_type='text/plain', client=None,
predefined_acl=None):
"""Upload contents of this blob from the provided string.
.. note::
Expand Down Expand Up @@ -1020,12 +1052,17 @@ def upload_from_string(self, data, content_type='text/plain', client=None):
``NoneType``
:param client: Optional. The client to use. If not passed, falls back
to the ``client`` stored on the blob's bucket.
:type predefined_acl: str
:param predefined_acl: (Optional) predefined access control list
"""
data = _to_bytes(data, encoding='utf-8')
string_buffer = BytesIO(data)
self.upload_from_file(
file_obj=string_buffer, size=len(data),
content_type=content_type, client=client)
content_type=content_type, client=client,
predefined_acl=predefined_acl)

def create_resumable_upload_session(
self,
Expand Down
Loading

0 comments on commit a3c3774

Please sign in to comment.