Images API examples

Learn how to upload, transform, store, and serve images dynamically using the Images API. This example extends the Guestbook sample from the getting started guide, and modifies it to let a user upload an avatar with their greeting.

Creating an Image model in Datastore

You need to update the model from the guestbook sample to store the uploaded image as a blob.

class Greeting(ndb.Model):
    """Models a Guestbook entry with an author, content, avatar, and date."""
    author = ndb.StringProperty()
    content = ndb.TextProperty()
    avatar = ndb.BlobProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

Uploading user images

You will need to modify the HTML form to enable the user to upload an image:

  1. Add a field that enables the user to select a file from their computer to upload.

  2. Add the enctype attribute to the form tag and specify this is a multi-part form post.

    self.response.out.write("""
          <form action="/sign?%s"
                enctype="multipart/form-data"
                method="post">
            <div>
              <textarea name="content" rows="3" cols="60"></textarea>
            </div>
            <div><label>Avatar:</label></div>
            <div><input type="file" name="img"/></div>
            <div><input type="submit" value="Sign Guestbook"></div>
          </form>
          <hr>
          <form>Guestbook name: <input value="%s" name="guestbook_name">
          <input type="submit" value="switch"></form>
        </body>
      </html>""" % (urllib.urlencode({'guestbook_name': guestbook_name}),
                    cgi.escape(guestbook_name)))

  3. Update the Guestbook handler to get the image data from the form post and store it as a blob in the datastore.

    class Guestbook(webapp2.RequestHandler):
        def post(self):
            guestbook_name = self.request.get('guestbook_name')
            greeting = Greeting(parent=guestbook_key(guestbook_name))
    
            if users.get_current_user():
                greeting.author = users.get_current_user().nickname()
    
            greeting.content = self.request.get('content')
    
            avatar = self.request.get('img')
            avatar = images.resize(avatar, 32, 32)
            greeting.avatar = avatar
            greeting.put()
    
            self.redirect('/?' + urllib.urlencode(
                {'guestbook_name': guestbook_name}))

Transforming images

To create 32x32 avatars you will need to:

  1. Import the google.appengine.api.images module.

    from google.appengine.api import images

  2. Call the resize function and pass in the image data.

    avatar = images.resize(avatar, 32, 32)

Dynamically serving images

To serve images, you will need to:

  1. Create an image handler that dynamically serves images off the /img path.

    class Image(webapp2.RequestHandler):
        def get(self):
            greeting_key = ndb.Key(urlsafe=self.request.get('img_id'))
            greeting = greeting_key.get()
            if greeting.avatar:
                self.response.headers['Content-Type'] = 'image/png'
                self.response.out.write(greeting.avatar)
            else:
                self.response.out.write('No image')

  2. Update the HTML to display these dynamically served images.

    self.response.out.write('<div><img src="/img?img_id=%s"></img>' %
                            greeting.key.urlsafe())
    self.response.out.write('<blockquote>%s</blockquote></div>' %
                            cgi.escape(greeting.content))

You will need to update the Guestbook's HTML to pass the key of the greeting to the image handler as it gets the img_id from the request.

Deploying the app to App Engine

To upload the guestbook app, run the following command from within the guestbook directory of your application where the app.yaml and index.yaml files are located:

gcloud app deploy app.yaml index.yaml

The Datastore indexes might take some time to generate before your application is available. If the indexes are still in the process of being generated, you will receive a NeedIndexError message when accessing your app. This error is transient, so try a little later if at first you receive this error.

To learn more about deploying your app from the command line, see Deploying A Python App.

Viewing your deployed application

To launch your browser and view the app at http://[YOUR_PROJECT_ID].appspot.com, run the following command:

gcloud app browse
Was this page helpful? Let us know how we did:

Send feedback about...

App Engine standard environment for Python