Blog

Waldemar Kornewald on October 18, 2011

Using dev_appserver with Python 2.7 on App Engine

Starting with SDK 1.6.0 the App Engine fully supports Python 2.7. This article originally described a workaround for getting Python 2.7 running on SDK 1.5.5. Now it only describes how to port your app.yaml and request handlers to Python 2.7.

The following instructions work with any WSGI-compliant web framework. I'll explain how to use Python 2.7 with djangoappengine/Django-nonrel at the end of this post. Yes, Django-nonrel works with Python 2.7 on App Engine. This blog (All Buttons Pressed) is already running on Python 2.7 with threadsafe: yes.

Let's start with a simple app.yaml for Python 2.5:

application: yourappid
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: handler.py

The handler.py file looks like this:

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

# This can be any WSGI handler. Here we just use webapp.
application = webapp.WSGIApplication(...)

def main():
    run_wsgi_app(application)

if __name__ == '__main__':
    main()

In order to use Python 2.7 you have to change your app.yaml like this:

application: yourappid
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /.*
  script: handler.application

Here we've changed the runtime to python27, added threadsafe: yes and modified the last line (script) to point to the WSGI handler directly instead of just the handler.py module.

Also, our handler.py can be simplified like this:

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

application = webapp.WSGIApplication(...)

In other words, we've just removed main(). Note, webapp users would normally port their code to webapp2, but that's not really relevant for this post, so let's just ignore that detail.

That's all you need to use Python 2.7 on both the production server and dev_appserver.

Using djangoappengine with Python 2.7

If you're a Django-nonrel / djangoappengine user you can just change your app.yaml to look like this:

application: yourappid
version: 1
runtime: python27
api_version: 1
threadsafe: yes

builtins:
- remote_api: on

inbound_services:
- warmup

libraries:
- name: django
  version: latest

handlers:
- url: /_ah/queue/deferred
  script: djangoappengine.deferred.handler.application
  login: admin

- url: /_ah/stats/.*
  script: djangoappengine.appstats.application

- url: /.*
  script: djangoappengine.main.application

That's it. djangoappengine will take care of the rest. Note that the libraries section is currently necessary due to a bug in SDK 1.6.0. Since you're already deploying a custom django package it shouldn't be necessary to enable Django in the libraries section. The App Engine team will fix this bug in the next SDK release.

Happy porting!