Pretty URIs with Google App Engine

Getting pretty URI/URLs in Google app engine is easy, but the first time I looked I wasn’t able to figure out how to do it from Google’s documentation, so I’ve saved some instructions here.

The first step is to add in some regex capture groups when sending your URIs to WSGIApplication. The code below specifies that ScoreHandler can receive either one argument like /game/<game_id>/score or two arguments like /game/<game_id>/score/<score_id>.

from google.appengine.ext   import webapp
from handlers.score_handler import ScoreHandler
from wsgiref.handlers       import CGIHandler

def main():
    application = webapp.WSGIApplication([
        (r'/game/(.+)/score/(.+)', ScoreHandler), 
        (r'/game/(.+)/score',      ScoreHandler), 
    ], debug=True)

if __name__ == '__main__':

When one of these URI expressions is hit, WSGIApplication will expect to find a function in the corresponding handler with a number of arguments equal to the number of regex groups that were matched.

from google.appengine.ext import webapp

class ScoreHandler(webapp.RequestHandler):

    # Receives one or two arguments, depending on which URI 
    # was accessed
    def get(self, game_id, score_id=None):
            "game_id = %s, score_id = %s" % (game_id, score_id)

As shown above, we can also map multiple URIs with different numbers of regex capture groups to the same handler class by providing a function with default arguments. In this example, if /game/2/score was hit, game_id would have a value of 2 while score_id would be None. If /game/2/score/3 was hit, game_id would be 2 and score_id would be 3.

Posted on March 9, 2009 from Calgary


My name is Brandur. I'm a polyglot software engineer and part-time designer working at Heroku in San Francisco, California. I'm a Canadian expat. My name is Icelandic. Drop me a line at

Aside from technology, I'm interested in energy and how it relates to our society, travel, longboarding, muay thai, symphonic metal, and the guitar.

If you liked this article, consider finding me on Twitter.