deck.cc

Django 1.2 on Google App Engine

If you want a solid python web framework on neat hosting infrastructure, Django and Google App Engine form a good match.

Requirements

Please make sure you already have installed the latest App Engine Python SDK . Being familiar with Django and App Engine is not a must but certainly won't hurt.

Django 1.2

Django can be used on Google App Engine and quite some people do, but how-to information is a bit scarce and often outdated. Since Django 1.2 was released just a few days ago we thought it would be nice to document the setup process.

Google App Engine currently has a limit of 3000 files per project. That might sound quite generous, but Django is a large framework (over 1200 files). In combination with a nontrivial project and some static assets like images and JavaScript libraries this limit could get nasty. Luckily with Python you can zipimport modules and we are going to take advantage of that later on.

The following steps will create a file named django.zip which contains the Django 1.2 source code. These instructions should work on Ubuntu Lucid Lynx and Mac OS X Snow Leopard but will probably also run on similar systems.

    
# we create a directory to work with
mkdir django-on-appengine
cd django-on-appengine

# grab and extract the current django release tarball
curl -L http://www.djangoproject.com/download/1.2.1/tarball/ -o Django-1.2.1.tar.gz
tar xzvf Django-1.2.1.tar.gz

# zip the current django source
cd Django-1.2.1
zip -r ../django.zip django/
cd ..

# remove everything except django.zip
rm -rf Django-1.2*
    
   

Django App Engine Helper from Google

There are two popular projects which aid in Django deployment on App Engine:

We mainly use google-app-engine-django at deck.cc as the project is supported by many Googlers and only does what is necessary to get Django up and running on App Engine.

If you are interested in additional features like tighter ORM integration you might also want to take a look at djangoappengine. We consider NoSQL/NonRel support for Django as too experimental at the moment and therefore prefer no datastore abstractions at all meanwhile.

Now we are going to set up a bare project to start with.

    
# grab and extract the google-app-engine-django project
curl -L http://github.com/clones/google-app-engine-django/tarball/master -o google-app-engine-django.tar.gz
tar --strip-components=1 -xzvf google-app-engine-django.tar.gz

# remove the tarball
rm google-app-engine-django.tar.gz

# create a symlink to the google app engine sdk (only necessary on linux)
ln -s /usr/local/google_appengine .google_appengine
    
   

You should now be able to start the development server as usual, though it will use the development server of the App Engine SDK instead of Django's.

    
python2.5 manage.py runserver
    
   

Error Logging

Django's development server outputs informative error messages including stack traces to the console. While Django renders helpful error pages in development mode, this can be very useful for debugging Ajax requests, cron jobs and the taskqueue. Since we use the development server of the App Engine SDK we need to make some small adjustments to get the same effect.

Adding the following lines to main.py will do. Here we adapted the code from the Django on App Engine tutorial for Django 1.2 Signals.

    
import logging
import django.core.signals
import django.dispatch.dispatcher

def log_exception(*args, **kwds):
    logging.exception('Exception in request:')

# Log errors.
django.dispatch.Signal.connect(
    django.core.signals.got_request_exception, log_exception)

# Unregister the rollback event handler.
django.dispatch.Signal.disconnect(
    django.core.signals.got_request_exception,
    django.db._rollback_on_exception)
    
   

Additionally we will also be able to benefit from these logs in production as they will be browsable and searchable in the App Engine Console Dashboard for your project.

Error Logging in App Engine Console Dashboard on an Application in Production

Performance Metrics with Appstats

Google recently released Appstats , which is an application performance measuring tool combined with a web based analytics-like web interface for browsing statistics about certain events. It was written by Guido van Rossum and hooks into the RPC framework of App Engine which is used to communicate with various services. This causes some (rather negligible) overhead but is especially useful for measuring things like memcache, image processing, datastore query performance et al.

Appstats Web Interface

Using Appstats is fairly easy because App Engine offers a Django middleware which integrates it into the request handling cycle of our application. Therefore we just need to edit settings.py and prepend the following middleware to MIDDLEWARE_CLASSES.

    
MIDDLEWARE_CLASSES = (
    'google.appengine.ext.appstats.recording.AppStatsDjangoMiddleware',

    # ...
)
    
   

Finally we add another route to our app.yaml configuration file. This will enable us to browse the analytics web interface.

    
- url: /stats.*
  script: $PYTHON_LIB/google/appengine/ext/appstats/ui.py
    
   

If you used the route pattern of the example above, you will be able to browse the performance statistics at /stats. They will be locked down to admins only even if you don't restrict its access explicitly.

Enjoy

Congratulations, you are ready to start hacking on your Django App Engine project. All of Django's features that don't rely on the existance of a RDBMS should work without a hitch and some things like the User model is patched by google-app-engine-django. It certainly will help to look into the documentation of each of the projects.

Further Reading