Serving files from a Google Cloud Storage Bucket

116 views
Skip to first unread message

Julian Sanchez

unread,
Oct 16, 2017, 7:09:07 AM10/16/17
to web2py-users
I'm in the process of 'upgrading' an old Web2py application hosted on GAE that performs a fair amount of file manipulation.  The original version used the blobstore to create files, and the 'default/download' function was modified to serve those blobs like this (abbreviated):

        blob_key = request.args[0]
        blob_info = blobstore.get(blob_key)

        response.headers['X-AppEngine-BlobKey'] = blob_key;
        response.headers['Content-Type'] = blob_info.content_type;
        response.headers['Content-Disposition'] = "attachment; filename=%s" % blob_info.filename

        blob_reader = blob_info.open()
        response.stream(blob_reader)

Blobstore is now gone so I changed the code to use a GCS bucket.  Everything works well everywhere in the application as far as uploading and creating files internally, but when I want to offer those files for download I can't get it to work.  As you know, files on GCS buckets are accessible via their path (i.e. cloudstore.open(file_path)) however if I try something like:

file_reader = cloudstore.open(file_path)
response.stream(file_reader)

all I get is a blank webpage with 'None' written on it, and no file.
I can't (and don't want to) offer the actual file_path for download straight to the user because the bucket permissions are private and web2py is the only one authorized to access it.

I've tried a number of combinations (setting headers with content-type and content-disposition versus no headers, response.write versus response.stream, reading file to StringIO object and try to stream/write that object instead) but none of them work.  I'm at a point where I'm blindly trying different code combinations.  Does anybody have a working code example for this?

Thanks,
Julian

Bernhard Radermacher

unread,
Oct 17, 2017, 4:25:48 AM10/17/17
to web2py-users
not having worked with GAE, so I might be completely off base, but try to build an absolute path like

os.path.join(request.folder, file_path)

just an idea.....

Julian Sanchez

unread,
Oct 20, 2017, 6:32:18 AM10/20/17
to web2py-users
In case this helps anyone else, here is how I got it to work:

response.headers['Content-Type'] = 'application/octet-stream'
response
.headers['Content-Disposition'] = 'attachment;filename=%s' % file_name
file_reader
= cloudstore.open(file_path)
return file_reader.read()

any other attempts to use response.write or response.body kept returning 'None'
Reply all
Reply to author
Forward
0 new messages