Google’s App Engine offers an intriguing new rapid development opportunity. Long story short, Google is offering developers a chance to write apps against its App Engine API. Included are features such as a simple web app framework (appropriately called webapp), an object-based datastore (complete with GQL query language), Google authentication and support for memcache.
The webapp framework feels like a mix of Java servlet programming and MVC frameworks like Pylons or TurboGears. You write classes to handle requests and can optionally hook in a templating framework, such as mako. I’ve just started playing with App Engine, but put together a simple getting-started structure that I think is worth sharing. Walk through the Hello, World! sample to get an idea of what the api is like.
In my app.yaml file, I map all requests to main.py
... handlers: - url: /.* script: main.py
main.py simply initializes the web application.
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from homehandler import *
application = webapp.WSGIApplication(
[('/', HomeHandler),
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
I've also created a base class for my handlers, AbstractHandler. This class provides a method for subclasses to wire in mako templates. The mako code is modified a little from this posting. I also create a property view_data that can be populated by subclasses and is passed to the templates in the render_template function.
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from mako.template import Template
import os
class AbstractHandler(webapp.RequestHandler):
def __init__(self):
self._view_data = {}
@property
def view_data(self):
return self._view_data
def render_template(self, action):
#assume default directory maps to home
if len(self.request.path) > 1:
controller = self.request.path
else:
controller = "\home"
view_path = "views%s/%s.mako" % (controller, action)
path = os.path.join(os.path.dirname(__file__), view_path)
templ = Template(filename=path)
self.response.out.write(templ.render(**self._view_data))
Finally, subclasses extend this class and implement the necessary verb methods.
from abstracthandler import *
class HomeHandler(AbstractHandler):
def get(self):
self.view_data["some_foo"] = "some foo"
self.view_data["some_bar"] = "some bar"
self.render_template("index")
The mako template (from the above mentioned blog) looks like this:
${some_foo} likes the ${some_bar}
Now I’ll be the first to admit, there’s nothing too exciting about my approach (and I’m still getting my feet wet with Python), but I think it’s a little better laid out than the samples you’ll find in the docs. I’m personally not a fan of having a giant web handler file with all handlers (same goes for models).