21

Is there a python equivalent to the getPublicUrl PHP method?

$public_url = CloudStorageTools::getPublicUrl("gs://my_bucket/some_file.txt", true);

I am storing some files using the Google Cloud Client Library for Python, and I'm trying to figure out a way of programatically getting the public URL of the files I am storing.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
orcaman
  • 6,263
  • 8
  • 54
  • 69

4 Answers4

58

Please refer to https://cloud.google.com/storage/docs/reference-uris on how to build URLs.

For public URLs, there are two formats:

http(s)://storage.googleapis.com/[bucket]/[object]

or

http(s)://[bucket].storage.googleapis.com/[object]

Example:

bucket = 'my_bucket'
file = 'some_file.txt'
gcs_url = 'https://%(bucket)s.storage.googleapis.com/%(file)s' % {'bucket':bucket, 'file':file}
print gcs_url

Will output this:

https://my_bucket.storage.googleapis.com/some_file.txt

Gustavo Straube
  • 3,744
  • 6
  • 39
  • 62
Danny Hong
  • 1,474
  • 13
  • 21
  • 1
    If it's within a subfolder then 'https://my_bucket.storage.googleapis.com/subfolder/some_file.txt' – user984003 Aug 15 '15 at 23:34
  • 2
    As of 2018 the pattern has updated to: `https://storage.cloud.google.com/[BUCKET_NAME]/[OBJECT_NAME]` The link above is still valid and includes more info. – crgt Feb 22 '18 at 23:34
  • 1
    The link in the answer points to https://cloud.google.com/storage/docs/access-public-data, which says to use `http://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]` – pmiguelpinto90 Jul 23 '18 at 11:22
  • as of June 19, you cannot do this via gcloud api's in python. I am sure they will have this in the forthcoming features. – user9484528 Jun 25 '19 at 18:33
6

You need to use get_serving_url from the Images API. As that page explains, you need to call create_gs_key() first to get the key to pass to the Images API.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
4

Daniel, Isaac - Thank you both.

It looks to me like Google is deliberately aiming for you not to directly serve from GCS (bandwidth reasons? dunno). So the two alternatives according to the docs are either using Blobstore or Image Services (for images).

What I ended up doing is serving the files with blobstore over GCS.

To get the blobstore key from a GCS path, I used:

blobKey = blobstore.create_gs_key('/gs' + gcs_filename)

Then, I exposed this URL on the server - Main.py:

app = webapp2.WSGIApplication([
...
    ('/blobstore/serve', scripts.FileServer.GCSServingHandler),
...

FileServer.py:

class GCSServingHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self):
        blob_key = self.request.get('id')
        if (len(blob_key) > 0):
            self.send_blob(blob_key)
        else: 
            self.response.write('no id given')
orcaman
  • 6,263
  • 8
  • 54
  • 69
  • Just to be clear, using `send_blob()` or `images.get_serving_url()` still counts against the more-expensive GAE bandwidth quota, and not the less-expensive GCS egress quota, correct? – Zach Young Dec 04 '14 at 20:27
  • I think get_serving_url produces a url that is GCS direct, and therefore less expensive. It has an additional benefit of applying automatic image resize as part of url parameter – Michael Jun 25 '15 at 13:25
2

It's not available, but I've filed a bug. In the meantime, try this:

import urlparse

def GetGsPublicUrl(gsUrl, secure=True):
  u = urlparse.urlsplit(gsUrl)
  if u.scheme == 'gs':
    return urlparse.urlunsplit((
        'https' if secure else 'http',
        '%s.storage.googleapis.com' % u.netloc,
        u.path, '', ''))

For example:

>>> GetGsPublicUrl('gs://foo/bar.tgz')
'https://foo.storage.googleapis.com/bar.tgz'
Isaac
  • 758
  • 5
  • 16
  • The secure version of the public url will not work for the default bucket. It reports a net::ERR_INSECURE_RESPONSE. But you can use: https://storage.googleapis.com/// – voscausa Mar 11 '14 at 01:27
  • Where do you see that? The certificate I get for https://foo.storage.googleapis.com is valid for *.storage.googleapis.com. – Isaac Mar 13 '14 at 03:38
  • I have the problem in Chrome and Firefox using the secure link which starts with the bucket. In Firefox I can add an exception. Example: https://jinjacms2.appspot.com.storage.googleapis.com/eurocodicil/Disclaimer.pdf – voscausa Mar 13 '14 at 11:25