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:
- A basic understanding of the Twisted Plugin System (i.e.,
the
twisted.pluginmodule) is necessary, however, step-by-step instructions will be given. Reading The Twisted Plugin System is recommended, in particular theExtending an Existing Program
section. - The Application infrastructure is used in Twisted Application Plugins; in particular, you should know how to expose your program's functionality as a Service.
- In order to parse command line arguments, the Twisted
Application Plugin system relies
on
twisted.python.usage, which is documented in Using usage.Options.
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:
- MyProject - Top level directory
- myproject - Python package
- __init__.py
- myproject - Python package
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
- Create a twistd plugin
- Use it from your development environment
- Install it correctly and use it in deployment