watch this The wheels are turning, slowly turning. home
Twisted Web in 60 seconds: rpy scripts (or, how to save yourself some typing) 2009-10-02

Welcome to the eighth installment of “Twisted Web in 60 seconds”. In the previous installment, I griped about how much typing I had to do for each of the examples. The goal of this installment is to show you another way to run a Twisted Web server with a custom resource which doesn’t require as much code.

The feature I’m talking about is called an rpy script. An rpy script is a Python source file which defines a resource and can be loaded into a Twisted Web server. The advantages of this approach are that you don’t have to write code to create the site or set up a listening port with the reactor. That means fewer lines of code that aren’t dedicated to the task you’re trying to accomplish.

There are some disadvantages, though. An rpy script must have the extension .rpy. This means you can’t import it using the usual Python import statement. This means it’s hard to re-use code in an rpy script. This also means you can’t easily unit test it. The code in an rpy script is evaluated in an unusual context, So, while rpy scripts may be useful for testing out ideas, I would not recommend them for much more than that.

Okay, with that warning out of the way, let’s dive in. First, as I mentioned, rpy scripts are Python source files with the .rpy extension. So, open up an appropriately named file (for example, example.rpy) and put this code in it:

import time

from twisted.web.resource import Resource

class ClockPage(Resource):
    isLeaf = True
    def render_GET(self, request):
        return "<html><body>%s</body></html>" % (time.ctime(),)

resource = ClockPage()

You may recognize this as the resource from the first dynamic rendering example. What’s different is what you don’t see: I didn’t import reactor or Site. There’s no calls to listenTCP or run. Instead, and this is the core idea for rpy scripts, I just bound the name resource to the resource I want the script to serve. Every rpy script must bind this name, and this name is the only thing Twisted Web will pay attention to in an rpy script.

All that’s left is to drop this rpy script into a Twisted Web server. There are a few ways to do this. The simplest way is with twistd:

$ twistd -n web --path .

Hit http://localhost:8080/example.rpy to see it run. You can pass other arguments here too. twistd web has options for specifying which port number to bind, whether to set up an HTTPS server, and plenty more. You can also pass options to twistd here, for example to configure logging to work differently, to select a different reactor, etc. For a full list of options, see twistd –help and twistd web –help.

That’s it for rpy scripts for now. I’ll probably make use of them in future examples to keep the focus on the new material. And speaking of which, check out the next installment to learn about asynchronous rendering.