Question

I am trying to create a blobstore upload process for a GCE Application coded in Python.

I do not have a webapp to use the blobstore_handlers process.

What is the process for upload blobs in this manner?

I have implemented the create upload URL endpoint:

from google.appengine.ext import blobstore


def blobstore_get_upload_url(self, request):

    upload_url = blobstore.create_upload_url('/upload')
    return self.construct_valid_response(StatusResponse, upload_url)

The URL returned is not a valid route on the APP:

http://127.0.0.1:8080/_ah/upload/ag1kZXZc3RyaW5nLWltciILEhVfX0Jsb2JVcGxvYWRTZXNzaW9uX18YgICAgICAgAsM

When I try to POST to this URL I get this error:

The url "/api" does not match any handlers.

My app.yaml:

handlers:
# Endpoints handler
- url: /_ah/spi/.*
    script: app_api.APPLICATION

My question:

Do I need to create a separate script outside of my endpoints application to upload the blob to? Or is there a way to direct the upload URL to another endpoints method to handle the upload process?

When I try to specify a another endpoint on the app as the upload URL it is ignored.

EX:

upload_url = blobstore.create_upload_url('/api#p/Api/v1/api.app.blobstore_upload')

Note I have removed the app name from the above URL and replaced it with API, but the URL I am using is a valid URL in the app.

I see that the old file process is deprecated and replaced with the google cloud storage process. Is this the direction I should be heading?

Was it helpful?

Solution 2

I resolved this by using the gcs API functions:

https://cloud.google.com/appengine/docs/python/googlecloudstorageclient/functions

EX:

default_retry_params = gcs.RetryParams(initial_delay=0.2,
                                   max_delay=5.0,
                                   backoff_factor=2,
                                   max_retry_period=15)

gcs.set_default_retry_params(default_retry_params)

bucket_name = os.environ.get('BUCKET_NAME',
                         app_identity.get_default_gcs_bucket_name())

gcs_file = gcs.open('/' + bucket_name + '/' + str(c.key.id()) + '/' + request.image_key,
                    'w',
                    options={'x-goog-meta-creator': str(u.key.id()),
                             'x-goog-meta-image-key': request.image_key,
                             'x-goog-meta-container': str(c.key.id())})

gcs_file.write(base64.b64decode(request.encoded_image))
gcs_file.close()

OTHER TIPS

Blobstore upload works in several steps:

  1. Create a one-time upload url via create_upload_url(callbackUrl). Send this to client.
  2. Client MUST then use multipart/form-data POST request to upload data to that Url.
  3. Google extracts the contents, stores it into blobstore and then calls your callbackUrl. You need to have a handler defined on that Url. Handler receives the blobstore keys Google created for the content uploaded.

This is a great post on using Blobstore with an iOS client. The example is in Java so please comment if there are difficulties recreating the backend code in Python.

https://brunofuster.wordpress.com/2011/03/11/uploading-an-image-from-iphone-to-appengine-blobstore-using-vraptor/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top