EngineLight – A Small Google App Engine Framework

Note: I abandoned this project and removed it from github. I had fun playing with AppEngine and python, but python is a poor fit for my mode of problem solving and never really tore me away from smalltalk-ish languages like Ruby and Objective-C. I much prefer heroku for easy cloud deployment. Cheers.

I’m playing around with Google’s App Engine product as I sit in on a course I used to teach, now taught by Charles Severence. I’ve been fairly vocal about my thoughts on the move away from Ruby to Python for this course, although I can see the draw of using App Engine for education. Deployment can be a bitch and often setting up a box with various languages for student projects is beyond the ability and budget of a small school’s IT department. I want to be helpful when the App Engine part of course comes around, so I need to spend some time and make a App Engine app.

App Engine provides a built-in Model class that saves to Google’s Big Table, a built-in template library roughly ported from Django’s templates, and a webapp framework for exposing both on the web.

For someone coming from a more robust environment, developing with the provided webapp framework is painful. Here’s sample from Google’s doc:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class MainPage(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'
    self.response.out.write('Hello, webapp World!')

application = webapp.WSGIApplication(
                                     [('/', MainPage)],
                                     debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()

Google’s apparently taking a very PHPesque page-structured app approach with their framework. Where a class = a page tied together with some basic routing (the [('/', MainPage)] bits). It’s definitely not MVC and after spending three years doing rapidly development thanks to a structured pattern I’m in no mood to return to an earlier time.

Google says you can run any any WSGI-compliant framework- “including Django, CherryPy, Pylons” – and has included the entire Django framework. I found this to be slightly untrue. It’s like Django, but modified. And I kept getting tripped up in the subtle differences between documented features and actual implementation once it was on App Engine.

The same goes for the other frameworks listed: they all require a bit of monkey patching to run properly. Someone with a lot of experience with one of these frameworks will probably go through the trouble of modifying their preferred framework to gain the benefit of using it on App Engine. But even if you do get them working, I hear there are whole parts that don’t run – or don’t run properly – on Google’s slightly off-color python environment.

My own attempt to get Pylons (which seemed most Merb-like and therefore caught my eye) working properly with the appengine-money library failed miserably.

So, I figured: why bother? If the framework is being gutted to work on App Engine and Google provides most of MVC in the included Model class and Template language there isn’t much left. I’m big skinny controller, fat model believer and think controllers should only be used as a flow control technique (hence their name) that essentially pour data into a specific template. They’re just a way to parcel out your code into tiny manageable, patterned bits. In Rails controllers, we rarely have more than the typical seven actions (index, show, new, create, edit, update, destroy) and a before filter or two.

I started EngineLight, a small encapsulation layer for the App Engine webapp framework. It’s pretty rickety right now, but has bits of the things I’ve needed so far. I plan on expanding it as write a sample app for App Engine. I’m using the Python Routes libary which is a quite robust port of Rails’ routing system. Really the only code I’ve needed to write myself so far is a tiny AbstractController class that encapsulates the existing Request and Response objects and builds a response using the built-in template library. An example controller can be as simple as

from application_controller import ApplicationController
from models import Note

class NotesController(ApplicationController):
  def index(self):
    notes = Note.all().fetch()
    self.view['notes'] = notes
    self.render_view('entries/index.html')

And a route might be

def routing(m):
  m.resource('note','notes')
  return m

This will automatically call NotesController.index() when someone browses to /notes/ and NotesController.show() with params['id'] set when someone goes to /notes/12.

Check out the EngineLight on github. You can install it straight from there with

easy_install easy_install http://github.com/trek/engine-light/tree/master%2Fdist%2Fenginelight-0.1dev-py2.5.egg?raw=true

generate a new project with

paster create -t enginelight myappname

and from inside that app create models (name them singularly) and controllers (plurals, please) with

paster controller Notes

paster model Note

routes will be a .py file in YourProject/congif/routes.py

Enjoy, but expect it to break a lot until I’m done! I’ve abandoned this project. I was able to structure an app to work much like the patterns in Rails, but don’t really have any interest in extracting that into a reusable library. App Engine is neat, but as a Ruby (mostly) developer it’s not really my cup of tea.


About this entry