Chapter 6. Deploying Twisted Applications

Twisted is an engine for producing scalable, cross-platform network servers and clients. Making it easy to deploy these applications in a standardized fashion in production environments is an important part of a platform like this getting wide-scale adoption.

To that end, Twisted provides an application infrastructure: a reusable and configurable way to deploy a Twisted application. It allows a programmer to avoid boilerplate code by hooking an application into existing tools for customizing the way it is run, including daemonization, logging, using a custom reactor, profiling code, and more.

The application infrastructure has five main components: services, applications, TAC files, plugins, and the twistd command-line utility. To illustrate this infrastructure, we’ll turn the echo server from Chapter 2 into an application. Example 6-1 reproduces the server code.

from twisted.internet import protocol, reactor

class Echo(protocol.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)

class EchoFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return Echo()

reactor.listenTCP(8000, EchoFactory())
reactor.run()

When writing a Twisted program as a regular Python file, the developer is responsible for writing code to start and stop the reactor and to configure the program. Under the Twisted application infrastructure, protocol implementations live in a module, services using those protocols are registered in a Twisted application configuration (TAC) file, and the reactor and configuration are managed by an external utility.

To turn our echo server into an echo application, we can follow a simple algorithm:

In our case, this means creating an instance of the TCPServer service, which will use our EchoFactory to create instances of the Echo protocol on port 8000.

The code for managing the reactor will be taken care of by twistd, which we’ll discuss next. The application code is now split into two files: echo.py, shown in Example 6-2; and echo_server.tac, shown in Example 6-3.

twistd (pronounced “twist-dee”) is a cross-platform utility for deploying Twisted applications. It runs TAC files and handles starting and stopping the application. As part of Twisted’s batteries-included approach to network programming, twistd comes with a number of useful configuration flags, including flags for daemonizing the application, specifying the location of log files, dropping privileges, running in a chroot, running under a non-default reactor, or even running the application under a profiler.

We can run our echo server application with:

twistd -y echo_server.tac

In this simplest case, twistd starts a daemonized instance of the application, logging to twistd.log, with a PID stored in twisted.pid. After starting and stopping the application, the log looks like this:

2012-11-19 22:23:07-0500 [-] Log opened.
2012-11-19 22:23:07-0500 [-] twistd 12.1.0 (/usr/bin/python 2.7.1) ...
2012-11-19 22:23:07-0500 [-] reactor class: twisted.internet.select...
2012-11-19 22:23:07-0500 [-] echo.EchoFactory starting on 8000
2012-11-19 22:23:07-0500 [-] Starting factory <echo.EchoFactory ...
2012-11-19 22:23:20-0500 [-] Received SIGTERM, shutting down.
2012-11-19 22:23:20-0500 [-] (TCP Port 8000 Closed)
2012-11-19 22:23:20-0500 [-] Stopping factory <echo.EchoFactory ...
2012-11-19 22:23:20-0500 [-] Main loop terminated.
2012-11-19 22:23:20-0500 [-] Server Shut Down.

To suppress daemonization and log to stdout, pass -n (--nodaemon). For a full list of twistd’s capabilities, run twistd --help or consult the manpage.

Without writing any code ourselves, we got free daemonization and logging. Running a service using the Twisted application infrastructure allows developers to skip writing boilerplate code for common server functionalities.

An alternative to the TAC-based system for running Twisted applications is the plugin system. While the TAC system makes it easy to register simple hierarchies of predefined services within an application configuration file, the plugin system makes it easy to register custom services as subcommands of the twistd utility and to extend the command-line interface to an application.

Using this system:

To extend a program using the Twisted plugin system, all you have to do is create objects that implement the IPlugin interface and put them in a particular location where the plugin system knows to look for them.

Having already converted our echo server to a Twisted application, transformation into a Twisted plugin is straightforward. Alongside the echo module from before, which contains the Echo protocol and EchoFactory definitions, we add a directory called twisted, containing a subdirectory called plugins containing our echo plugin definition. Graphically, the directory structure is:

echoproject/
├── echo.py
└── twisted
    └── plugins
        └── echo_plugin.py

Let’s make the port our echo service uses configurable through twistd. Example 6-4 shows the necessary logic.

A service plugin needs a minimum of two components:

With this plugin defined, if we run twistd from the top-level project directory our echo server will now show up as a server option in the output of twistd --help, and running twistd echo --port=1235 will start an echo server on port 1235.

twistd ships with many commands that make it easy to spin up simple services with zero lines of code. Here are some examples:

I don’t know about you, but I get pretty excited by the networking power of these simple twistd one-liners.

This chapter introduced the Twisted application infrastructure for configuring and deploying Twisted programs in a standardized fashion.

There are two main ways of deploying applications using this infrastructure: TAC files and plugins. TAC files are simpler but less extensible, making them ideal for simple server deployments that want to take advantage of Twisted’s built-in deployment features, like logging and daemonization. Plugins have a higher initial development cost but expose a clear API for extending your application. Plugins are ideal for applications that need a stable interface for third-party developers or more control over plugin discovery and loading.

The Twisted Core HOWTO provides an overview of the application framework and TAC files, as well as information about the plugin philosophy and twistd plugins specifically.

Twisted comes with a pluggable authentication system for servers called Twisted Cred, and a common use of the plugin system is to add authentication to an application. Twisted Cred is discussed in detail in Chapter 9.

  1. Converting a Twisted program into a TAC-based or plugin-based service follows a straightforward algorithm that you can practice on any of the servers we build in this book.

    Try converting the chat server from Example 2-5 to a Twisted application, and converting the nonblocking web server from Example 4-8 to a plugin-based service.

  2. All of the commands listed in twistd --help are plugins that you can browse in the Twisted source code at twisted/plugins/. Pick one and read through the service definition.