Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google App Engine (Python) - Uploading a file (image)

I want the user to be able to upload images to Google App Engine. I have the following (Python):

class ImageData(ndb.Model):
     name = ndb.StringProperty(indexed=False)
     image = ndb.BlobProperty()

Information is submitted by the user using a form (HTML):

<form name = "input" action = "/register" method = "post">
    name: <input type = "text" name = "name">
    image: <input type = "file" name = "image">
</form>

Which is then processed by:

class AddProduct(webapp2.RequestHandler):
    def post(self):
        imagedata = ImageData(parent=image_key(image_name))
        imagedata.name = self.request.get('name')
        imagedata.image = self.request.get('image')
        imagedata.put()

However, when I try to upload an image, lets say "Book.png", I get the error: BadValueError: Expected str, got u'Book.png'

Any idea what is going on? I have been working with GAE for quite some time, but this is the first time I had to use blobs.

I used this link: https://developers.google.com/appengine/docs/python/images/usingimages which uses db, not ndb. I also tried storing the image in a variable first like in the link: storedInfo = self.request.get('image') and then storing it: imagedata.image = ndb.Blob(storedInfo) Which ALSO gives me an error: AttributeError: 'module' object has no attribute 'Blob' Thanks in advance.

like image 455
Albraa Avatar asked Aug 23 '13 00:08

Albraa


People also ask

How do I upload a file to GCS bucket?

In the Google Cloud console, go to the Cloud Storage Buckets page. In the list of buckets, click on the name of the bucket that you want to upload an object to. In the Objects tab for the bucket, either: Drag and drop the desired files from your desktop or file manager to the main pane in the Google Cloud console.


2 Answers

Had the same prob.

just replace

imagedata.image = self.request.get('image')

with:

imagedata.image = str(self.request.get('image'))

also your form needs to have enctype="multipart/form-data

<form name = "input" action = "/register" method = "post" enctype="multipart/form-data">
like image 95
Orane Avatar answered Sep 27 '22 23:09

Orane


There is a great example in the documentation that describes how to upload files to the Blobstore using a HTML form: https://developers.google.com/appengine/docs/python/blobstore/#Python_Uploading_a_blob

The form should point to a url generated by blobstore.create_upload_url('/foo') and there should be a subclass of the BlobstoreUploadHandler at /foo like this:

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
  def post(self):
    upload_files = self.get_uploads('file')
    blob_info = upload_files[0]
    imagedata = ImageData(parent=image_key(image_name))
    imagedata.name = self.request.get('name')
    imagedata.image = blob_info.key()
    imagedata.put()

For this to work, you should change your data model such that in ImageData, image referes to a ndb.BlobKeyProperty().

You can serve your image simply from a url generated by images.get_serving_url(imagedata.image), optionally resized and cropped.

like image 22
pfalke Avatar answered Sep 27 '22 23:09

pfalke