Of late I am deving in parallel on a sample at home project for a few reasons including practicing skills both in architecture but also so I can get more exposure to new languages, with the most recent addition being PYTHON. The Google AppEngine currently supports PYTHON and JAVA, and since I am already doing a couple of things in JAVA I thought I would try my hand at PYTHON and I have to say, “I like it.”
Before I got onto the AppEngine, an immediate accompaniment to programming in PYTHON for the web was the DJango framework. When you start reading through even the first page of the starting tutorials, you realise how easy and fast it is to get up and running with a saleable application. The Google app engine includes features of DJango, but not all of them. One main example is the fact that Google has defined its own data store and ORM for use with the AppEngine.
So inside the web application, we would want to logically separate different handlers for different situations, and the example which I am including in this post is for a Forum. Two handlers immediately spring to mind being a handler to List all the forums and a handler to view an individual forum by id.
- /Forums
- /Forum/1/somename-of-the-forum
A colleague in the place were I work, pointed out a really handy function called slugify inside the DJango framework which simply took and string and made a url friendly version i.e. “The Forum” because “the-forum.” Unfortunately though, I think this is not included inside the Google AppEngine, so it will probably be best to create an implementation of a “Slug Field” for our objects, and then it will be easy to say something like “forum.slug().” I have not et implemented this yet, just up to the url rewriting part 
Yep, these functions are included inside the Google AppEngine, I was stupid for thinking otherwise. Check out the import and the implementation I used below on the last code snippet.
I have created a file called handlers.py but I think it will be better to separate the handlers by file and by topic area i.e. Forum, Thread, Post etc… but for this example, the two handlers I create are inside this 1 file. Also, my implementation of the handler is purely for example only, i.e. I am outputting a string so we can recognise the different behaviour in each handler.
ForumListHandler
class ForumListHandler(webapp.RequestHandler):
def get(self):
for item in Forum.all():
self.response.out.write("%s<br>" %
(item.title))
ForumViewHandler
class ForumViewHandler(webapp.RequestHandler):
def get(self,id,name):
self.response.out.write("you are are looking for forum %s with id of : %s" % (name,id))
If you notice in the second handler, the function has 3 parameters, which will become clear with the next code snippet how they are populated. The first handler will simply output a list of the forums, and the second will output a string which includes the values it will extract from the url of the get request.
I am currently paid to develop ASP.NET MVC where this syntax of automatically mapping a request with an overloaded function is very familiar and well structured. Inside the main.py file you have a block of code where you add your mappings to handlers. The following is the result of adding the required handlers for this example:
def main():
application = webapp.WSGIApplication([('/', MainHandler),
('/forums',ForumListHandler),
('/forum/(\d+)/(.*)',ForumViewHandler)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
Of course the url mapping uses regular expressions, and I think from looking at this, that it first checks that the number of matches it has made on the url, is equal to the number of parameters inside the handler. If this is a match it will then supply each parameter in the order in which they are matched using the regular expression. From the above you can see I first match a sequence of digits, so this fits in with my get function shown above with the first parameter after self being id.
UPDATE:
I changed my implementation of the url rewrite rules, and for the forum view I decided that I would make the parameter a slug, with an obvious rule that each slug is unique. The reason I did this, is because the entity key you get with an object inside the Google app engine, is not really the cleanest thing to put in there as it contains the entity type and guid and things. So below is the updated version and also an updated handler for the forum list handler so we can output the forums and follow the links. I will use the datastore admin tool to add some forums in. Oh, just to mention, when a new model is saved to the datastore, you automatically get a CRUD interface for it. A rough equivalence of this on Microsoft technology I would say is dynamic data, makes me wonder if they got inspiration from DJango for that.
def main():
application = webapp.WSGIApplication([('/', MainHandler),
('/forums',ForumListHandler),
('/forum/(.*)',ForumViewHandler)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
And the updated handlers, which now outputs the link, and the other which simply accepts the slug:
from google.appengine.ext import webapp
from models import Forum
from django.template import defaultfilters
class ForumViewHandler(webapp.RequestHandler):
def get(self,slug):
self.response.out.write("you are are looking for forum with slug of : %s" % (slug))
class ForumListHandler(webapp.RequestHandler):
def get(self):
for item in Forum.all():
self.response.out.write("<a href=\"/forum/%s\">%s</a><br>" %
(defaultfilters.slugify(item.title), item.title))
Cheers,
Andrew