2929
3030from gcloud ._helpers import _rfc3339_to_datetime
3131from gcloud ._helpers import _to_bytes
32- from gcloud ._helpers import _from_bytes
32+ from gcloud ._helpers import _to_unicode
3333from gcloud .credentials import generate_signed_url
3434from gcloud .exceptions import NotFound
3535from gcloud .exceptions import make_exception
@@ -280,35 +280,40 @@ def delete(self, client=None):
280280 """
281281 return self .bucket .delete_blob (self .name , client = client )
282282
283- def download_to_file (self , file_obj , key = None , client = None ):
283+ def download_to_file (self , file_obj , encryption_key = None , client = None ):
284284 """Download the contents of this blob into a file-like object.
285285
286286 .. note::
287287
288288 If the server-set property, :attr:`media_link`, is not yet
289289 initialized, makes an additional API request to load it.
290290
291- Downloading a file that has been encrypted with a
292- `customer-supplied`_ key::
291+ Downloading a file that has been encrypted with a `customer-supplied`_
292+ encryption key::
293293
294294 >>> from gcloud import storage
295295 >>> from gcloud.storage import Blob
296296
297297 >>> client = storage.Client(project='my-project')
298298 >>> bucket = client.get_bucket('my-bucket')
299- >>> key = 'aa426195405adee2c8081bb9e7e74b19'
299+ >>> encryption_key = 'aa426195405adee2c8081bb9e7e74b19'
300300 >>> blob = Blob('secure-data', bucket)
301301 >>> with open('/tmp/my-secure-file', 'wb') as file_obj:
302- >>> blob.download_to_file(file_obj, key=key)
302+ >>> blob.download_to_file(file_obj,
303+ ... encryption_key=encryption_key)
304+
305+ The ``encryption_key`` should be a str or bytes with a length of at
306+ least 32.
303307
304308 .. _customer-supplied: https://cloud.google.com/storage/docs/\
305309 encryption#customer-supplied
306310
307311 :type file_obj: file
308312 :param file_obj: A file handle to which to write the blob's data.
309313
310- :type key: str
311- :param key: Optional 32 byte key for customer-supplied encryption.
314+ :type encryption_key: str or bytes
315+ :param encryption_key: Optional 32 byte encryption key for
316+ customer-supplied encryption.
312317
313318 :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
314319 :param client: Optional. The client to use. If not passed, falls back
@@ -329,8 +334,8 @@ def download_to_file(self, file_obj, key=None, client=None):
329334 download .chunksize = self .chunk_size
330335
331336 headers = {}
332- if key :
333- _set_encryption_headers (key , headers )
337+ if encryption_key :
338+ _set_encryption_headers (encryption_key , headers )
334339
335340 request = Request (download_url , 'GET' , headers )
336341
@@ -342,14 +347,15 @@ def download_to_file(self, file_obj, key=None, client=None):
342347 # it has all three (http, API_BASE_URL and build_api_url).
343348 download .initialize_download (request , client ._connection .http )
344349
345- def download_to_filename (self , filename , key = None , client = None ):
350+ def download_to_filename (self , filename , encryption_key = None , client = None ):
346351 """Download the contents of this blob into a named file.
347352
348353 :type filename: string
349354 :param filename: A filename to be passed to ``open``.
350355
351- :type key: str
352- :param key: Optional 32 byte key for customer-supplied encryption.
356+ :type encryption_key: str or bytes
357+ :param encryption_key: Optional 32 byte encryption key for
358+ customer-supplied encryption.
353359
354360 :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
355361 :param client: Optional. The client to use. If not passed, falls back
@@ -358,16 +364,18 @@ def download_to_filename(self, filename, key=None, client=None):
358364 :raises: :class:`gcloud.exceptions.NotFound`
359365 """
360366 with open (filename , 'wb' ) as file_obj :
361- self .download_to_file (file_obj , key = key , client = client )
367+ self .download_to_file (file_obj , encryption_key = encryption_key ,
368+ client = client )
362369
363370 mtime = time .mktime (self .updated .timetuple ())
364371 os .utime (file_obj .name , (mtime , mtime ))
365372
366- def download_as_string (self , key = None , client = None ):
373+ def download_as_string (self , encryption_key = None , client = None ):
367374 """Download the contents of this blob as a string.
368375
369- :type key: str
370- :param key: Optional 32 byte key for customer-supplied encryption.
376+ :type encryption_key: str or bytes
377+ :param encryption_key: Optional 32 byte encryption key for
378+ customer-supplied encryption.
371379
372380 :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
373381 :param client: Optional. The client to use. If not passed, falls back
@@ -378,7 +386,8 @@ def download_as_string(self, key=None, client=None):
378386 :raises: :class:`gcloud.exceptions.NotFound`
379387 """
380388 string_buffer = BytesIO ()
381- self .download_to_file (string_buffer , key = key , client = client )
389+ self .download_to_file (string_buffer , encryption_key = encryption_key ,
390+ client = client )
382391 return string_buffer .getvalue ()
383392
384393 @staticmethod
@@ -392,8 +401,9 @@ def _check_response_error(request, http_response):
392401 error_info = request .url )
393402
394403 # pylint: disable=too-many-locals
395- def upload_from_file (self , file_obj , rewind = False , size = None , key = None ,
396- content_type = None , num_retries = 6 , client = None ):
404+ def upload_from_file (self , file_obj , rewind = False , size = None ,
405+ encryption_key = None , content_type = None , num_retries = 6 ,
406+ client = None ):
397407 """Upload the contents of this blob from a file-like object.
398408
399409 The content type of the upload will either be
@@ -412,17 +422,21 @@ def upload_from_file(self, file_obj, rewind=False, size=None, key=None,
412422 `lifecycle <https://cloud.google.com/storage/docs/lifecycle>`_
413423 API documents for details.
414424
415- Uploading a file with `customer-supplied`_ encryption::
425+ Uploading a file with a `customer-supplied`_ encryption key ::
416426
417427 >>> from gcloud import storage
418428 >>> from gcloud.storage import Blob
419429
420430 >>> client = storage.Client(project='my-project')
421431 >>> bucket = client.get_bucket('my-bucket')
422- >>> key = 'aa426195405adee2c8081bb9e7e74b19'
432+ >>> encryption_key = 'aa426195405adee2c8081bb9e7e74b19'
423433 >>> blob = Blob('secure-data', bucket)
424434 >>> with open('my-file', 'rb') as my_file:
425- >>> blob.upload_from_file(my_file, key=key)
435+ >>> blob.upload_from_file(my_file,
436+ ... encryption_key=encryption_key)
437+
438+ The ``encryption_key`` should be a str or bytes with a length of at
439+ least 32.
426440
427441 .. _customer-supplied: https://cloud.google.com/storage/docs/\
428442 encryption#customer-supplied
@@ -440,8 +454,9 @@ def upload_from_file(self, file_obj, rewind=False, size=None, key=None,
440454 :func:`os.fstat`. (If the file handle is not from the
441455 filesystem this won't be possible.)
442456
443- :type key: str
444- :param key: Optional 32 byte key for customer-supplied encryption.
457+ :type encryption_key: str or bytes
458+ :param encryption_key: Optional 32 byte encryption key for
459+ customer-supplied encryption.
445460
446461 :type content_type: string or ``NoneType``
447462 :param content_type: Optional type of content being uploaded.
@@ -486,8 +501,8 @@ def upload_from_file(self, file_obj, rewind=False, size=None, key=None,
486501 'User-Agent' : connection .USER_AGENT ,
487502 }
488503
489- if key :
490- _set_encryption_headers (key , headers )
504+ if encryption_key :
505+ _set_encryption_headers (encryption_key , headers )
491506
492507 upload = Upload (file_obj , content_type , total_bytes ,
493508 auto_transfer = False )
@@ -530,8 +545,8 @@ def upload_from_file(self, file_obj, rewind=False, size=None, key=None,
530545 self ._set_properties (json .loads (response_content ))
531546 # pylint: enable=too-many-locals
532547
533- def upload_from_filename (self , filename , content_type = None , key = None ,
534- client = None ):
548+ def upload_from_filename (self , filename , content_type = None ,
549+ encryption_key = None , client = None ):
535550 """Upload this blob's contents from the content of a named file.
536551
537552 The content type of the upload will either be
@@ -556,8 +571,9 @@ def upload_from_filename(self, filename, content_type=None, key=None,
556571 :type content_type: string or ``NoneType``
557572 :param content_type: Optional type of content being uploaded.
558573
559- :type key: str
560- :param key: Optional 32 byte key for customer-supplied encryption.
574+ :type encryption_key: str or bytes
575+ :param encryption_key: Optional 32 byte encryption key for
576+ customer-supplied encryption.
561577
562578 :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
563579 :param client: Optional. The client to use. If not passed, falls back
@@ -568,11 +584,11 @@ def upload_from_filename(self, filename, content_type=None, key=None,
568584 content_type , _ = mimetypes .guess_type (filename )
569585
570586 with open (filename , 'rb' ) as file_obj :
571- self .upload_from_file (file_obj , content_type = content_type , key = key ,
572- client = client )
587+ self .upload_from_file (file_obj , content_type = content_type ,
588+ encryption_key = encryption_key , client = client )
573589
574- def upload_from_string (self , data , content_type = 'text/plain' , key = None ,
575- client = None ):
590+ def upload_from_string (self , data , content_type = 'text/plain' ,
591+ encryption_key = None , client = None ):
576592 """Upload contents of this blob from the provided string.
577593
578594 .. note::
@@ -594,8 +610,9 @@ def upload_from_string(self, data, content_type='text/plain', key=None,
594610 :param content_type: Optional type of content being uploaded. Defaults
595611 to ``'text/plain'``.
596612
597- :type key: str
598- :param key: Optional 32 byte key for customer-supplied encryption.
613+ :type encryption_key: str or bytes
614+ :param encryption_key: Optional 32 byte encryption key for
615+ customer-supplied encryption.
599616
600617 :type client: :class:`gcloud.storage.client.Client` or ``NoneType``
601618 :param client: Optional. The client to use. If not passed, falls back
@@ -607,7 +624,7 @@ def upload_from_string(self, data, content_type='text/plain', key=None,
607624 string_buffer .write (data )
608625 self .upload_from_file (file_obj = string_buffer , rewind = True ,
609626 size = len (data ), content_type = content_type ,
610- key = key , client = client )
627+ encryption_key = encryption_key , client = client )
611628
612629 def make_public (self , client = None ):
613630 """Make this blob public giving all users read access.
@@ -905,7 +922,7 @@ def __init__(self, bucket_name, object_name):
905922def _set_encryption_headers (key , headers ):
906923 """Builds customer encyrption key headers
907924
908- :type key: str
925+ :type key: str or bytes
909926 :param key: 32 byte key to build request key and hash.
910927
911928 :type headers: dict
@@ -916,5 +933,5 @@ def _set_encryption_headers(key, headers):
916933 key_hash = base64 .b64encode (sha256_key ).rstrip ()
917934 encoded_key = base64 .b64encode (key ).rstrip ()
918935 headers ['X-Goog-Encryption-Algorithm' ] = 'AES256'
919- headers ['X-Goog-Encryption-Key' ] = _from_bytes (encoded_key )
920- headers ['X-Goog-Encryption-Key-Sha256' ] = _from_bytes (key_hash )
936+ headers ['X-Goog-Encryption-Key' ] = _to_unicode (encoded_key )
937+ headers ['X-Goog-Encryption-Key-Sha256' ] = _to_unicode (key_hash )
0 commit comments