Writing a Twisted Application Plugin for twistd

  1. Goals
  2. A note on .tap files
  3. Alternatives to TAP
  4. Creating the plugin
  5. Conclusion

This document describes writing extension subcommands for the twistd command, as a way to facilitate the deployment of your applications. (This feature was added in Twisted 2.5)

The target audience of this document are those that have developed a Twisted application which needs a command line-based deployment mechanism.

There are a few prerequisites to understanding this document:

Goals

After reading this document, the reader should be able to expose their Service-using application as a subcommand of twistd, taking into consideration whatever was passed on the command line.

A note on .tap files

Readers may be confused about a historical file type associated with Twisted, the .tap file. This was a kind of file that was generated by a program named mktap and which twistd can read. .tap files are deprecated; this document has nothing to do with them, although the technology described herein is very closely related to the old system. TAP, in the modern Twisted vernacular, means Twisted Application Plugin.

Alternatives to TAP

The major alternative to the TAP mechanism is the .tac file, which is a simple script to be used with the twistd -y/--python parameter. The TAP plugin system exists to offer a more extensible command-line-driven interface to your application. For more information on .tac files, see the document Using the Twisted Application Framework.

Creating the plugin

The following directory structure is assumed of your project:

During development of your project, Twisted plugins can be loaded from a special directory in your project, assuming your top level directory ends up in sys.path. Create a directory named twisted containing a directory named plugins, and add a file named myproject.py to it. This file will contain your plugin. Note that you should not add any __init__.py files to this directory structure.

In this file, define an object which provides the interfaces twisted.plugin.IPlugin and twisted.application.service.IServiceMaker.

The tapname attribute of your IServiceMaker provider will be used as the subcommand name in a command like twistd [subcommand] [args...], and the options attribute (which should be a usage.Options subclass) will be used to parse the given args.

from zope.interface import implements

from twisted.python import usage
from twisted.plugin import IPlugin
from twisted.application.service import IServiceMaker
from twisted.application import internet

from myproject import MyFactory


class Options(usage.Options):
    optParameters = [["port", "p", 1235, "The port number to listen on."]]


class MyServiceMaker(object):
    implements(IServiceMaker, IPlugin)
    tapname = "myproject"
    description = "Run this! It'll make your dog happy."
    options = Options

    def makeService(self, options):
        """
        Construct a TCPServer from a factory defined in myproject.
        """
        return internet.TCPServer(int(options["port"]), MyFactory())

# Now construct an object which *provides* the relevant interfaces

# The name of this variable is irrelevant, as long as there is *some*
# name bound to a provider of IPlugin and IServiceMaker.

serviceMaker = MyServiceMaker()

Now running twistd --help should print myproject in the list of available subcommands, followed by the description that we specified in the plugin. twistd -n myproject would, assuming we defined a MyFactory factory inside myproject, start a listening server on port 1235 with that factory.

Conclusion

You should now be able to

Index

Version: 2.5.0