Rollin’ With Google App Engine, 80′s Style

Building a web application with Google App Engine is quick and easy, and you have the power of the google distributed content delivery network and the ‘BigTable’ database at your disposal. So what’s it good for?

When I was 14 my Dad bought a Commodore 64. I poured over the manuals, taught myself C64 BASIC, bought C64 programming magazines and created a stack of audio cassettes full of unfinished projects. It was awesome fun being able to create sounds and make things happen on screen.

Then about 2 years later I discovered girls and didn’t become interested in technology again for some years. I often wonder if I could have reached Bill Gates-like heights if only I had continued to apply myself to technology instead of fluorescent colored shirts, skinny ties, and Blue-Light discos.

Dave Winer said that because of Google App Engine, "Python is the new BASIC". And my first experience with App Engine did indeed generate that same sense of fun that C64 BASIC did way back in my embarrassing past. With zero Python experience and just the App Engine guestbook tutorial under my belt, I managed to build a functional (albeit utterly pointless), slightly amusing web service called "Now Roll…". Now Roll.. simulates Dungeons and Dragons-style dice rolling. It was straight forward and simple to create — I’m talking push-button simple. Google App Engine is my new Commodore 64.

A screenshot of the Now Roll... home page

So what exactly is Google App Engine? Well, it includes most of the pieces you usually need to assemble together to create a web application. It has a simple framework component called ‘webapp’, a database referred to as the ‘datastore’, and a deployment system. Once completed you can deploy your web application to run on Google’s infrastructure. It also has a fully functional local development environment that is a duplicate of the live environment.

Once you download and install the SDK You can start practicing with the local development environment straight away, but to deploy an application you have to register your app first with your Google account. which includes account confirmation via SMS. The free accounts are also limited to 3 applications — I assume to avoid 5 million variations of "Hello, world!" being deployed. But this limitation might only be during the preview-release period.

I have two big tips for beginners: complete the Getting Started tutorial and use the Launcher application (which is bundled with the SDK) to build your first project. When you add a new web application using the Launcher app, it generates an application shell for you, all the files needed for a basic web app, that you can run straight away. It only outputs "Hello world!", but it works. Once you have the shell, you can start playing!

A screenshot of the Google App Engine Launcher

A basic GAE application has the following components:

  • An application configuration file called app.yaml in which you specify routes (or URL patterns) and the python script file that will be executed if the requested URL matches the pattern.
  • One or more script files (as specified in the app.yaml file) that each specify a list of URL patterns and the Python classes responsible for handling the URLs.
  • One or more request handling classes that define a get and/or a post method in order to be able to handle HTTP GET or POST requests to the specified URL patterns. They read the requests and compose the responses, for which there’s a templating engine you can use.
  • Optionally, one or more model classes that define the data structure of the entities you want to store in the datastore.

The app.yaml file allows you to specify routes (or URL patterns) called ‘handlers’: you match a URL pattern to a python script file that will be executed if the requested URL matches the pattern. The default app contains a single handler:

handlers:
- url: .*
  script: main.py

This default configuration specifies that GAE will execute the main.py file for all request URLs. If, like me, you just want to dive in, just use this default setup, it’s fine for a simple app. You can also specify static routes to things like CSS files which is explained in the Getting Started tutorial.

The main.py script file creates an instance of the webapp.WSGIApplication class in a function called main and then calls this function. This is all boilerplate code that is automatically generated for you. Here’s what it looks like:

def main():
  application = webapp.WSGIApplication([('/', MainHandler)],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()

The creation of the application object includes two parameters: a list of request handlers and the debug flag. The debug flag, if True, will cause GAE to output stack traces to the browser for runtime errors. The request handlers are each a Python tuple that matches a URL pattern (a regular expression) with a Python class. The default setup has the root URL '/' matched to the MainHandler class. You can have multiple handlers specified in this way. For my Now Roll… app I needed three handlers:

application = webapp.WSGIApplication([('/', MainHandler),
                                      ('/rolls/(.*)', ArchivedRoll),
                                      ('/(.*)', RollHandler)],
                                     debug=True)

One handler for the home page ('/', MainHandler), one for the permalinks to archived dice rolls ('/rolls/(.*)', ArchivedRoll) and one for the dice rolling function ('/(.*)', RollHandler). You have to list them from most specific to least specific, as the first matching pattern is the one that is executed. The specified python classes must be subclasses of the webapp.RequestHandler class and need to define a get and/or a post method in order to be able to handle HTTP GET or POST requests to the specified URL patterns. The default MainHandler class looks like this:

class MainHandler(webapp.RequestHandler):

  def get(self):
    self.response.out.write('Hello world!')

I have also included groups in the regular expressions, for example '/rolls/(.*)'. Handily, these matching fragments are passed as arguments to the get and post methods of the handling classes. My ArchivedRoll class uses this feature to get easy access to the key value of the archived roll:

class ArchivedRoll(webapp.RequestHandler):
  def get(self,key):
    # retrieve roll from datastore using the key value...
    # return the roll data to the browser using a template...

To use the GAE datastore you’ll need one or more model classes. There are no tables in the GAE datastore, your python model classes define the data structure and the datastore automatically handles storage, retrieval and index generation. Items in the datastore are known as ‘entities’. You need to import the Google db module: from google.appengine.ext import db and your model classes must be subclasses of db.Model.

In my Now Roll… application I want to store every dice roll and to do so I use this DiceRoll class:

class DiceRoll(db.Model):
  roll = db.StringProperty()
  results = db.ListProperty(int)
  outcome = db.IntegerProperty()
  date = db.DateTimeProperty(auto_now_add=True)

A model class is very simple; it provides a type name (a ‘kind’ in GAE parlance): DiceRoll, and a list of named properties to store for each entity. To store an entity you create a new instance of your model class, set the property values and then call the object’s put method.

dr = DiceRoll()
dr.roll = '2d6'
dr.results = [1,2]
dr.outcome = 3
dr.put()

The entity is now in the database. All entities automatically receive a unique identifier that you can retrieve using the object’s key() method like so:

key = dr.key()

You can retrieve a specific entity from the datastore using its key like so:

roll = db.get(key)

You can run datastore queries using an API or GQL, Google’s SQL-like query language. If I wanted to add a feature to my Now Roll… app that listed the last 10 dice rolls in reverse date order, the query would look something like this using the API:

rolls_query = DiceRoll.all().order('-date')
rolls = rolls_query.fetch(10)

The equivalent query using GQL is:

rolls = db.GqlQuery("SELECT * FROM DiceRoll "
                    "ORDER BY date DESC LIMIT 10")

This is all very simple and quite straight forward. For more complex relationships you can define an entity to be the parent of one or more other entities and then use that relationship in queries.

Once the request has been handled by your class method it can then output a response. The self.response.out.write method simply outputs the string argument it is supplied. The content type of the response is text/html unless you specify a different value using: self.response.headers["Content-Type"] = 'type' before any output.

The alternative (and preferred) method of output is to use templates. The template module bundled with the GAE SDK uses Django’s templating engine. To use it you need to import the template module: from google.appengine.ext.webapp import template, and the os module from the Python standard library: import os. Here’s an excerpt from the template file that displays an archived dice roll:

<h1 id="page_title">Now Roll {{ roll.roll }}</h1>
<div id="roll_info">
  <div id="outcome">{{ roll.roll }} = <span id="result">{{ roll.outcome }}</span>
    <p id="permalink">(<a href="/rolls/{{ id }}">Result permalink</a>)</p>
  </div>
</div>

The {{...}} tokens are placeholders for data that can be inserted by your request handler class’ response like so:

roll = db.get(key)
template_values = {
  'roll': roll,
  'id': roll.key(),
}
path = os.path.join(os.path.dirname(__file__), 'archive.html')
self.response.out.write(template.render(path, template_values))

The roll value in the template_values array above is an instance of the DiceRoll model class and all of that class’ properties are available in the template. So {{ roll.outcome }} in the template will be replaced by the outcome property value of the roll object.

A screenshot of a Now Roll... archived dice roll page

The job of creating the Now Roll… API was made very easy through the use of templates. The only difference between the webpage version and the XML version of a dice roll result is the template file used to render the response and the response Content-Type value.

Deployment to the Google servers is literally a single click on the button labeled ‘Deploy’ if you use the Google App Engine Launcher client. There is zero setup required for this; once deployed, your app is live and distributed.

That’s Google App Engine in a nutshell. There’s a handful of other App Engine modules you can make use of like image manipulation, caching and the Users API for integration with Google Accounts.

Even though GAE has a collection of useful libraries, it’s noticeably missing a testing framework. Frameworks like Rails have done a lot to popularize the use of automated unit testing, so it’s absence may turn some developers away. It’d be a nice feature to have one click unit testing to match the ease of the one-click deployment feature.

Kevin has mentioned previously that although it’s friendly to beginners, applications need to be written specifically for GAE, which is likely to deter some developers from making use of the platform. Although I imagine it’s possible to write a separate module to interface your existing application with the Google framework, I wonder, if you already have a commercial application and a team of developers, if it’s worth your time to port it to GAE.

The datastore may also trip up a few developers as they grapple with it’s non-relational nature. For example, the problem of counting records in the datastore has already come up in the GAE forum. You cannot simply do a COUNT(). But, I expect that as more developers sign up for the platform, more usage patterns will be developed and tested and best-practice usage patterns will eventually rise to the top.

One thing I predict GAE will be an excellent platform for is single-purpose web services. I’m not talking something frivolous like dice rolling, but some thing useful like a data collection service or an image manipulation service. A small generic component that can be used in a larger application but separated out and hosted on GAE to save application resources. A great example is this OpenID Provider app enabling you to sign into any site supporting openID using your Google Account credentials.

One aspect of GAE that I haven’t seen mentioned anywhere else yet is that it integrates with Google Apps for Your Domain. When you create a GAE application you can limit access to your registered domain users: hello company intranet! With GAE, GAfYD becomes a complete software solution for organizations, especially distributed organizations. I can see huge cost savings for a company that can avoid having to purchase servers and bandwidth and the ongoing administration costs of a self-hosted intranet.

For me though, apart from the mundane commercial aspects, Google App Engine represents something like the Commodore 64. You know a personal computer that doesn’t do much on its own but is flexible, programmable, inspiring, and fun. You use it to tinker with stuff, finding out how stuff works, trying out ideas for new gizmos, and building custom tools. It embodies the spirit of 80′s era personal computing (but without the bad fashion sense).

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Anonymous

    Although there’s no testing framework, a presentation at Google I/O outlined a pretty simple set of practices. I haven’t found the presentation on YouTube, but this guy blogged it: http://yousefourabi.com/cloud-computing/google-app-engine-best-practices
    Basic idea is that you can upload a new version that is accessible by a slight changed in the URL. Then make it live when you’re done testing.

  • http://tetlaw.id.au atetlaw

    Thanks Mr Anon, that’s a really useful link.

  • bob

    There is a testing framework..