Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion storage/cloud-client/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
google-cloud-pubsub==0.39.1
google-cloud-storage==1.14.0
google-cloud-storage==1.15.0
84 changes: 78 additions & 6 deletions storage/cloud-client/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def make_blob_public(bucket_name, blob_name):


def generate_signed_url(bucket_name, blob_name):
"""Generates a signed URL for a blob.
"""Generates a v2 signed URL for downloading a blob.

Note that this method requires a service account key file. You can not use
this if you are using Application Default Credentials from Google Compute
Expand All @@ -269,6 +269,62 @@ def generate_signed_url(bucket_name, blob_name):
return url


# [START storage_generate_signed_url_v4]
def generate_download_signed_url_v4(bucket_name, blob_name):
"""Generates a v4 signed URL for downloading a blob.

Note that this method requires a service account key file. You can not use
this if you are using Application Default Credentials from Google Compute
Engine or from the Google Cloud SDK.
"""
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(blob_name)

url = blob.generate_signed_url(
version='v4',
# This URL is valid for 15 minutes
expiration=datetime.timedelta(minutes=15),
# Allow GET requests using this URL.
method='GET')

print('Generated GET signed URL:')
print(url)
print('You can use this URL with any user agent, for example:')
print('curl \'{}\''.format(url))
return url
# [END storage_generate_signed_url_v4]


# [START storage_generate_upload_signed_url_v4]
def generate_upload_signed_url_v4(bucket_name, blob_name):
"""Generates a v4 signed URL for uploading a blob using HTTP PUT.

Note that this method requires a service account key file. You can not use
this if you are using Application Default Credentials from Google Compute
Engine or from the Google Cloud SDK.
"""
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(blob_name)

url = blob.generate_signed_url(
version='v4',
# This URL is valid for 15 minutes
expiration=datetime.timedelta(minutes=15),
# Allow GET requests using this URL.
method='PUT',
content_type='application/octet-stream')

print('Generated PUT signed URL:')
print(url)
print('You can use this URL with any user agent, for example:')
print("curl -X PUT -H 'Content-Type: application/octet-stream' "
"--upload-file my-file '{}'".format(url))
return url
# [END storage_generate_upload_signed_url_v4]


def rename_blob(bucket_name, blob_name, new_name):
"""Renames a blob."""
storage_client = storage.Client()
Expand Down Expand Up @@ -296,7 +352,7 @@ def copy_blob(bucket_name, blob_name, new_bucket_name, new_blob_name):
destination_bucket.name))


if __name__ == '__main__':
def main():
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
Expand Down Expand Up @@ -350,6 +406,14 @@ def copy_blob(bucket_name, blob_name, new_bucket_name, new_blob_name):
'signed-url', help=generate_signed_url.__doc__)
signed_url_parser.add_argument('blob_name')

signed_url_download_v4_parser = subparsers.add_parser(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling the generate signed URL should be added to the switch statement below.

'signed-url-download-v4', help=generate_download_signed_url_v4.__doc__)
signed_url_download_v4_parser.add_argument('blob_name')

signed_url_upload_v4_parser = subparsers.add_parser(
'signed-url-upload-v4', help=generate_upload_signed_url_v4.__doc__)
signed_url_upload_v4_parser.add_argument('blob_name')

rename_parser = subparsers.add_parser('rename', help=rename_blob.__doc__)
rename_parser.add_argument('blob_name')
rename_parser.add_argument('new_name')
Expand All @@ -363,15 +427,15 @@ def copy_blob(bucket_name, blob_name, new_bucket_name, new_blob_name):

if args.command == 'create-bucket':
create_bucket(args.bucket_name)
if args.command == 'enable-default-kms-key':
elif args.command == 'enable-default-kms-key':
enable_default_kms_key(args.bucket_name, args.kms_key_name)
elif args.command == 'delete-bucket':
delete_bucket(args.bucket_name)
if args.command == 'get-bucket-labels':
elif args.command == 'get-bucket-labels':
get_bucket_labels(args.bucket_name)
if args.command == 'add-bucket-label':
elif args.command == 'add-bucket-label':
add_bucket_label(args.bucket_name)
if args.command == 'remove-bucket-label':
elif args.command == 'remove-bucket-label':
remove_bucket_label(args.bucket_name)
elif args.command == 'list':
list_blobs(args.bucket_name)
Expand Down Expand Up @@ -401,6 +465,10 @@ def copy_blob(bucket_name, blob_name, new_bucket_name, new_blob_name):
make_blob_public(args.bucket_name, args.blob_name)
elif args.command == 'signed-url':
generate_signed_url(args.bucket_name, args.blob_name)
elif args.command == 'signed-url-download-v4':
generate_download_signed_url_v4(args.bucket_name, args.blob_name)
elif args.command == 'signed-url-upload-v4':
generate_upload_signed_url_v4(args.bucket_name, args.blob_name)
elif args.command == 'rename':
rename_blob(args.bucket_name, args.blob_name, args.new_name)
elif args.command == 'copy':
Expand All @@ -409,3 +477,7 @@ def copy_blob(bucket_name, blob_name, new_bucket_name, new_blob_name):
args.blob_name,
args.new_bucket_name,
args.new_blob_name)


if __name__ == '__main__':
main()
24 changes: 24 additions & 0 deletions storage/cloud-client/snippets_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,30 @@ def test_generate_signed_url(test_blob, capsys):
assert r.text == 'Hello, is it me you\'re looking for?'


def test_generate_download_signed_url_v4(test_blob, capsys):
url = snippets.generate_download_signed_url_v4(
BUCKET,
test_blob.name)

r = requests.get(url)
assert r.text == 'Hello, is it me you\'re looking for?'


def test_generate_upload_signed_url_v4(capsys):
blob_name = 'storage_snippets_test_upload'
content = b'Uploaded via v4 signed url'
url = snippets.generate_upload_signed_url_v4(
BUCKET,
blob_name)

requests.put(url, data=content, headers={
'content-type': 'application/octet-stream'})

bucket = storage.Client().bucket(BUCKET)
blob = bucket.blob(blob_name)
assert blob.download_as_string() == content


def test_rename_blob(test_blob):
bucket = storage.Client().bucket(BUCKET)

Expand Down