Thursday, 16 June 2011

Hello, Python World (Django Edition)

I’ve been doing my Python Tropo development on top of Google App Engine, for the past couple of years. Out of the box, App Engine uses the webapp framework. But for my current “Hello, World” project, I decided to leave my App Engine comfort zone, and gain a different perspective. I took up the task of writing a “Hello, World”, Tropo Web API app, using the Django framework for Python.

 

Where We’re Headed

Here’s a sneak preview of the script we’ll be writing, with a critical “decorator” left out for now.

from django.http import HttpResponse from tropo import Tropo, Session def post(request): t = Tropo() t.say(['Hello world!']) json = t.RenderJson() print json return HttpResponse(json)

The Tropo Web API module is available as a download from github. The other included module here is Django, available from the Django Software Foundation website. The initial web request coming from Tropo will be a POST, so we name our function accordingly. The fact that the request is a POST adds a little wrinkle, which I’ll be discussing towards the end of this article.

But patience, please. We’re getting ahead of ourselves.

Components

I’ve got a Macbook running Snow Leopard, which comes standard with Apache and Python. So I needed to get:

Building and Installing mod_wsgi

I discovered that the best way to install mod_wsgi on my Mac was to do it “the old-fashioned way”, without uilizing a convenience tool like MacPorts.

tar xvf mod_wsgi-3.3.tar cd mod_wsgi-3.3 make sudo make install

I then edited my Apache httpd.conf file, to include the line:

LoadModule wsgi_module libexec/apache2/mod_wsgi.so

This enables the embedded Python interpreter, and further down, we’ll see how to point that interpreter to our Python code.

Building Django

Installing Django is simple. It boils down to:

tar xzvf Django-1.3.tar.gz cd Django-1.3 sudo python setup.py install

The Django Software Foundation website offers a great tutorial, on setting up Django for the first time. My advice is to follow along with this tutorial step, by step, to the point of slavishly naming your installation mysite, just like they do. That’ll mean one less level of indirection to deal with as you follow the twists and turns. Soon, you’ll come to the part about setting up your project, which you do with this command:

django-admin.py startproject mysite

Note: A project is not an app. It is an entire Django instance. Our hello app will be just one of potentially many apps living withing the mysite project. Here is the structure of mysite after initial creation:

mysite __init__.py manage.py settings.py trop.db urls.py

Here’s a description of these files:

  • trop.db : the name I chose for the app’s database. We won’t be using it in this example
  • settings.py : not much to do here except specify a database engine. I chose sqlite3, because it’s included with Django
  • manage.py : a utility script using for managing our Django project
  • urls.py : implements an “url dispatcher”. More on this below.

Creating our “hello” app

Now we’re ready to create our hello app. We can do so, with the following command, issued from the mysites directory:

python manage.py startapp hello

At this point, the entire directory structure we’ve created looks like this:

__init__.py manage.py settings.py trop.db urls.py hello/ __init__.py models.py tests.py views.py

This then, is our framework, all erected, consisting of our overall Django instance, or project, mysites and within it, a single app, hello.

Knitting together Apache, Django, and mod_wsgi

We have some unfinished business in the Apache httpd.conf file, which is to tell mod_wsgi where to find our Django project. Again, there’s a great tutorial that walks us through this process, but the crucial item to insert the following line into httpd.conf:

WSGIScriptAlias / /path/to/mysite/apache/django.wsgi

And here’s what the contents of that django.wsgi file should be:

import osimport sys path = '/path/to/mysite/' if path not in sys.path: sys.path.append(path1) os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()

Setting up urls.py

Now it’s back to our url dispatcher, urls.py. For “Hello, World” all we really need here is:

urlpatterns = patterns('', (r'^index.json$', 'hello.views.post') )

This says that for the url index.json, we should run the post function inside the hello app, which lives in a file called views.py. This latter file is provided by the framework setup, and all we need to do is customize it. Finally, we are ready for our “Hello, World” code!

Putting Finishing Touches on our Hello, World Code

The code for our small greeting lives in hello/views.py. This is just as I presented it at the top of this article except for two new lines that implement a Python decorator:

from django.http import HttpResponse from tropo import Tropo, Session # Next 2 lines add "decorator" to bypass cookie requirement from django.views.decorators.csrf import csrf_exempt @csrf_exempt def post(request): t = Tropo() t.say(['hello wide world!']) json = t.RenderJson() print json return HttpResponse(json)

The Django framework deems it necessary for incoming POST requests to supply a special cookie, verifying the sender. In our case, the sender will be the Tropo engine, and as developers, we don’t have the ability to customize the incoming requests, at least the initial one, in this way.

So that’s we employ a special Python “decorator” operator, that has been developed for the purpose of bypassing this requirement, on a function-by-function basis. This csrf_exempt decorator comes with the Django distribution, so we can just import it.

Hello, World!

And there you have it. Hello, World. All you have to do now is:

  1. Head on over Tropo and use the GUI to create an app called “Hello, World”, and put in the url as http://web1.tunnlr.com/xxxxxx/wsgi-scripts/index.json where the first part, http://web1.tunnlr.com/xxxxxx/, is what Tunnlr gave you when you first signed up for this service.
  2. Fire up your Tunnlr shell, on the same port that Apache is listening on
  3. Make sure Apache is running
  4. Dial up the number that Tropo has associated with your app.
  5. Listen to those sweet, sweet words, that let you know: You are now officially hacking your Tropo apps in the Django framework!

Ted Gilchrist is the creator and primary maintainer of the Tropo Python library. He’s the developer of a number of Tropo applications including Talk-o-gram. You can find him on Twitter as egilchri.

©2011 The Tropo Blog. All Rights Reserved.

.

Related posts:

  1. New Guidelines for Naming Tropo Web API Language Libraries (ruby, PHP, python, C#)
  2. HOWTO: Working with the Python 3 branch of the Tropo Python Web API library
  3. Want to build voice, SMS, IM and Twitter apps in python? Tropo WebAPI library now available

Flickr - projectbrainsaver

www.flickr.com
projectbrainsaver's A Point of View photoset projectbrainsaver's A Point of View photoset