1
<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: Writing a Twisted Application Plugin for twistd</title><link href="../howto/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">Writing a Twisted Application Plugin for twistd</h1><div class="toc"><ol><li><a href="#auto0">Goals</a></li><li><a href="#auto1">A note on .tap files</a></li><li><a href="#auto2">Alternatives to TAP</a></li><li><a href="#auto3">Creating the plugin</a></li><li><a href="#auto4">Conclusion</a></li></ol></div><div class="content"><span></span><p>This document describes writing extension subcommands for
3
the <code>twistd</code> command, as a way to facilitate the deployment
4
of your applications. <em>(This feature was added in Twisted 2.5)</em></p><p>The target audience of this document are those that have developed
5
a Twisted application which needs a command line-based deployment
6
mechanism.</p><p>There are a few prerequisites to understanding this document:</p><ul><li>A basic understanding of the Twisted Plugin System (i.e.,
7
the <code class="API">twisted.plugin</code> module) is
8
necessary, however, step-by-step instructions will be
9
given. Reading <a href="plugin.html">The Twisted Plugin
10
System</a> is recommended, in particular the <q>Extending an
11
Existing Program</q> section.</li><li>The <a href="application.html">Application</a> infrastructure
12
is used in Twisted Application Plugins; in particular, you should
13
know how to expose your program's functionality as a Service.</li><li>In order to parse command line arguments, the Twisted
14
Application Plugin system relies
15
on <code>twisted.python.usage</code>, which is documented
16
in <a href="options.html">Using usage.Options</a>.</li></ul><h2>Goals<a name="auto0"></a></h2><p>After reading this document, the reader should be able to expose
17
their Service-using application as a subcommand
18
of <code>twistd</code>, taking into consideration whatever was passed
19
on the command line.</p><h2>A note on .tap files<a name="auto1"></a></h2><p>Readers may be confused about a historical file type associated
20
with Twisted, the <code>.tap</code> file. This was a kind of file that
21
was generated by a program named <code>mktap</code> and
22
which <code>twistd</code> can read. <code>.tap</code> files are
23
deprecated; this document has nothing to do with them, although the
24
technology described herein is very closely related to the old
25
system. <q>TAP</q>, in the modern Twisted vernacular, means <q>Twisted
26
Application Plugin</q>. </p><h2>Alternatives to TAP<a name="auto2"></a></h2><p>The major alternative to the TAP mechanism is the <code>.tac</code>
27
file, which is a simple script to be used with the
28
twistd <code>-y/--python</code> parameter. The TAP plugin system
29
exists to offer a more extensible command-line-driven interface to
30
your application. For more information on <code>.tac</code> files, see
31
the document <a href="application.html">Using the Twisted Application
32
Framework</a>.</p><h2>Creating the plugin<a name="auto3"></a></h2><p>The following directory structure is assumed of your project:</p><ul><li><strong>MyProject</strong> - Top level directory
33
<ul><li><strong>myproject</strong> - Python package
34
<ul><li><strong>__init__.py</strong></li></ul></li></ul></li></ul><p>
35
During development of your project, Twisted plugins can be loaded
36
from a special directory in your project, assuming your top level
37
directory ends up in sys.path. Create a directory
38
named <code>twisted</code> containing a directory
39
named <code>plugins</code>, and add a file
40
named <code>myproject.py</code> to it. This file will contain your
41
plugin. Note that you should <em>not</em> add any __init__.py files
42
to this directory structure.
44
In this file, define an object which <em>provides</em> the interfaces
45
<code class="API">twisted.plugin.IPlugin</code>
46
and <code class="API">twisted.application.service.IServiceMaker</code>.
47
</p><p>The <code>tapname</code> attribute of your IServiceMaker provider
48
will be used as the subcommand name in a command
49
like <code class="shell">twistd [subcommand] [args...]</code>, and
50
the <code>options</code> attribute (which should be
51
a <code base="twisted.python" class="API">usage.Options</code>
52
subclass) will be used to parse the given args.</p><pre class="python">
53
<span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">implements</span>
55
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">usage</span>
56
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">plugin</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IPlugin</span>
57
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span>.<span class="py-src-variable">service</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IServiceMaker</span>
58
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">internet</span>
60
<span class="py-src-keyword">from</span> <span class="py-src-variable">myproject</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">MyFactory</span>
63
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Options</span>(<span class="py-src-parameter">usage</span>.<span class="py-src-parameter">Options</span>):
64
<span class="py-src-variable">optParameters</span> = [[<span class="py-src-string">"port"</span>, <span class="py-src-string">"p"</span>, <span class="py-src-number">1235</span>, <span class="py-src-string">"The port number to listen on."</span>]]
67
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyServiceMaker</span>(<span class="py-src-parameter">object</span>):
68
<span class="py-src-variable">implements</span>(<span class="py-src-variable">IServiceMaker</span>, <span class="py-src-variable">IPlugin</span>)
69
<span class="py-src-variable">tapname</span> = <span class="py-src-string">"myproject"</span>
70
<span class="py-src-variable">description</span> = <span class="py-src-string">"Run this! It'll make your dog happy."</span>
71
<span class="py-src-variable">options</span> = <span class="py-src-variable">Options</span>
73
<span class="py-src-keyword">def</span> <span class="py-src-identifier">makeService</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">options</span>):
74
<span class="py-src-string">"""
75
Construct a TCPServer from a factory defined in myproject.
76
"""</span>
77
<span class="py-src-keyword">return</span> <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-variable">int</span>(<span class="py-src-variable">options</span>[<span class="py-src-string">"port"</span>]), <span class="py-src-variable">MyFactory</span>())
79
<span class="py-src-comment"># Now construct an object which *provides* the relevant interfaces
81
<span class="py-src-comment"># The name of this variable is irrelevant, as long as there is *some*
82
</span><span class="py-src-comment"># name bound to a provider of IPlugin and IServiceMaker.
84
<span class="py-src-variable">serviceMaker</span> = <span class="py-src-variable">MyServiceMaker</span>()
86
Now running <code class="shell">twistd --help</code> should
87
print <code>myproject</code> in the list of available subcommands,
88
followed by the description that we specified in the
89
plugin. <code class="shell">twistd -n myproject</code> would,
90
assuming we defined a <code>MyFactory</code> factory
91
inside <code>myproject</code>, start a listening server on port 1235
93
</p><h2>Conclusion<a name="auto4"></a></h2><p>You should now be able to</p><ul><li>Create a twistd plugin</li><li>Use it from your development environment</li><li>Install it correctly and use it in deployment</li></ul></div><p><a href="../howto/index.html">Index</a></p><span class="version">Version: 2.5.0</span></body></html>
b'\\ No newline at end of file'