How to serve cloudstorage files using app engine SDK

北战南征 提交于 2019-11-27 02:49:49

问题


In app engine I can serve cloudstorage files like a pdf using the default bucket of my application:

http://storage.googleapis.com/<appid>.appspot.com/<file_name>

But how can I serve local cloudstorage files in the SDK, without making use of a blob_key?

I write to the default bucket like this:

gcs_file_name = '/%s/%s' % (app_identity.get_default_gcs_bucket_name(), file_name)
with gcs.open(gcs_file_name, 'w') as f:
    f.write(data)

The name of the default bucket in the SDK = 'app_default_bucket'

In the SDK datastore I have a Kind: GsFileInfo showing: filename: /app_default_bucket/example.pdf

Update and workaround: You can get a serving url for NON image files like css, js and pdf.

gs_file = '/gs/%s/%s/%s' % (app_identity.get_default_gcs_bucket_name(), folder, filename)
serving_url = images.get_serving_url(blobstore.create_gs_key(gs_file))

回答1:


UPDATE I found this feature to serve cloudstorage files using the SDK:

This feature has not been documented yet.

http://localhost:8080/_ah/gcs/app_default_bucket/filename

This meands we do not need the img serving url to serve NON images as shown below !!!

To create e serving url for cloudstorage files like images, css, js and pdf's in the default_bucket, I use this code for testing(SDK) and GAE production:

IMPORTANT: the images.get_serving_url() works also for NON images in the SDK!!

In the SDK you stll need the blobstore to read a blob and create a serving url for a cloudstorage object.

I also added the code to read, write and upload cloudstorage blobs in the SDK and GAE production.

The code can be found here.




回答2:


This is the value that you see in the Development mode from app_identity_stub.py:

APP_DEFAULT_GCS_BUCKET_NAME = 'app_default_bucket'

The comments in this file explain it:

This service behaves the same as the production service, except using constant values instead of app-specific values

You should get the correct URL in your production code.

EDIT:

This is from the support forum:

In development mode, the app engine tools simulate Google Cloud Storage services locally. Objects in that simulated environment are non-persistent so your app is failing because the desired object doesn't exist in the local store. If you first create (and optionally write to) the object you're trying to read, it should work fine in dev mode (it did for me). Of course, objects in the production service are persistent so there's no need for that extra step when running your app in production mode (assuming the object already exists).

Hope that helps,

Marc Google Cloud Storage Team

This means you have to write a file first, then you can use it. If I understand correctly, you can use any bucket name for this purpose, including 'app_default_bucket'.




回答3:


I was here earlier looking for answers and just wanted to share what I found, now that I have it working.

You can do this now, and it's only a little painful. Tricking the image or blobstore API isn't supported and doesn't seem to work any longer.

See:

  • https://cloud.google.com/storage/docs/access-control/signed-urls
  • https://cloud.google.com/storage/docs/access-control/create-signed-urls-gsutil

If you sign your URLs, you can give auto-expiring links to your content, for anonymous or paywalled consumption. You wouldn't want to serve your whole site this way, but for a PDF or whatnot, this is a valid and semi-secure option.

Missing from the documentation, you might need to drop the newline for the canonical extended headers. The storage endpoint will tell you what it expects when the signature is bad.

Also, your host should be: https://storage-download.googleapis.com/

If you're using App Engine, then the GoogleAccessId is: <projectname>@appspot.gserviceaccount.com

See: app_identity.get_service_account_name()

Example of how to generate the signature:

from google.appengine.api import app_identity


def signFile(path, verb='GET', md5='', contentType='',
             expiration=''):
    signatureRequest = '{}\n{}\n{}\n{}\n{}'.format(
        verb, md5, contentType, expiration, path)

    return app_identity.sign_blob(signatureRequest)

That returns a tuple of (privateKey, binarySignature).

Now you need to construct the URL. The signature should be base64 encoded, then urlencoded. See the following for how to finish constructing the URL. You should probable use the download host mentioned above.

Example URL from the docs:

https://storage.googleapis.
com/example-bucket/cat.jpeg?GoogleAccessId=example@example-project.iam.gservicea
ccount.com&Expires=1458238630&Signature=VVUgfqviDCov%2B%2BKnmVOkwBR2olSbId51kSib
uQeiH8ucGFyOfAVbH5J%2B5V0gDYIioO2dDGH9Fsj6YdwxWv65HE71VEOEsVPuS8CVb%2BVeeIzmEe8z
7X7o1d%2BcWbPEo4exILQbj3ROM3T2OrkNBU9sbHq0mLbDMhiiQZ3xCaiCQdsrMEdYVvAFggPuPq%2FE
QyQZmyJK3ty%2Bmr7kAFW16I9pD11jfBSD1XXjKTJzgd%2FMGSde4Va4J1RtHoX7r5i7YR7Mvf%2Fb17
zlAuGlzVUf%2FzmhLPqtfKinVrcqdlmamMcmLoW8eLG%2B1yYW%2F7tlS2hvqSfCW8eMUUjiHiSWgZLE
VIG4Lw%3D%3D

I hope this helps someone!

Oh yeah, you only need to do all the signature stuff if your bucket isn't publicly accessible (read-all).



来源:https://stackoverflow.com/questions/22174903/how-to-serve-cloudstorage-files-using-app-engine-sdk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!