Python: how to save image?

This is what I got from downloading the link to the flex 4 file:

self.request =

Request: POST /UPLOAD Accept: text/* Cache-Control: no-cache Connection: Keep-Alive Content-Length: 51386 Content-Type: multipart/form-data; boundary=----------ei4cH2gL6ae0ei4ae0gL6GI3KM7ei4 Host: localhost:8080 User-Agent: Shockwave Flash ------------ei4cH2gL6ae0ei4ae0gL6GI3KM7ei4 Content-Disposition: form-data; name="Filename" 36823_117825034935819_100001249682611_118718_676534_n.jpg ------------ei4cH2gL6ae0ei4ae0gL6GI3KM7ei4 Content-Disposition: form-data; name="Filedata"; filename="36823_117825034935819_100001249682611_118718_676534_n.jpg" Content-Type: application/octet-stream      [AND OTHER STRANGE CHARACTERS] 

My class:

 class Upload(webapp.RequestHandler): def post(self): content = self.request.get("Filedata") return "done!" 

Now, what am I missing in the Upload class to save this file to disk? I have a few strange characters in the var contents (viewing in debug mode).

+4
source share
1 answer

App Engine cannot:

  • write to the file system. Applications must use the App Engine data store to store persistent data.

What you need to do is submit the form with the file upload field to the user.
When the form is submitted, the file is downloaded, and Blobstore creates a blob from the contents of the file and returns the blob key, useful for retrieving and serving the blob later.
The maximum size of an object is 2 gigabytes.

Here is a working snippet you can try:

 #!/usr/bin/env python # import os import urllib from google.appengine.ext import blobstore from google.appengine.ext import webapp from google.appengine.ext.webapp import blobstore_handlers from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app class MainHandler(webapp.RequestHandler): def get(self): upload_url = blobstore.create_upload_url('/upload') self.response.out.write('<html><body>') self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url) self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit" name="submit" value="Submit"> </form></body></html>""") class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): def post(self): upload_files = self.get_uploads('file') blob_info = upload_files[0] self.redirect('/serve/%s' % blob_info.key()) class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler): def get(self, resource): resource = str(urllib.unquote(resource)) blob_info = blobstore.BlobInfo.get(resource) self.send_blob(blob_info) def main(): application = webapp.WSGIApplication( [('/', MainHandler), ('/upload', UploadHandler), ('/serve/([^/]+)?', ServeHandler), ], debug=True) run_wsgi_app(application) if __name__ == '__main__': main() 

EDIT1:
in your specific case, you can use BlobProperty (limited to 1 MB) to store your request:

 class Photo(db.Model): imageblob = db.BlobProperty() 

then adapt your webapp.RequestHandler to save your request:

 class Upload(webapp.RequestHandler): def post(self): image = self.request.get("Filedata") photo = Photo() photo.imageblob = db.Blob(image) photo.put() 

EDIT2:
You do not need to change the app.yaml application, just add a new handler and map it in your WSGI. To get a saved photo, you must add another handler to serve your photos:

 class DownloadImage(webapp.RequestHandler): def get(self): photo= db.get(self.request.get("photo_id")) if photo: self.response.headers['Content-Type'] = "image/jpeg" self.response.out.write(photo.imageblob) else: self.response.out.write("Image not available") 

then map the new DownloadImage class:

 application = webapp.WSGIApplication([ ... ('/i', DownloadImage), ... ], debug=True) 

You could get the images using a url like this:

 yourapp/i?photo_id = photo_key 

As requested, if for some odd reason you really want to serve your images using this type of URL www.mysite.com/i/photo_key.jpg , you can try:

 class Download(webapp.RequestHandler): def get(self, photo_id): photo= db.get(db.Key(photo_id)) if photo: self.response.headers['Content-Type'] = "image/jpeg" self.response.out.write(photo.imageblob) else: self.response.out.write("Image not available") 

with slightly different display:

 application = webapp.WSGIApplication([ ... ('/i/(\d+)\.jpg', DownloadImage), ... ], debug=True) 
+6
source

All Articles