1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
3
<title>Twisted Documentation: Using the Twisted Application Framework</title>
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
8
<h1 class="title">Using the Twisted Application Framework</h1>
9
<div class="toc"><ol><li><a href="#auto0">Introduction</a></li><ul><li><a href="#auto1">Audience</a></li><li><a href="#auto2">Goals</a></li></ul><li><a href="#auto3">Overview</a></li><li><a href="#auto4">Using application</a></li><ul><li><a href="#auto5">twistd and tac</a></li><li><a href="#auto6">Customizing twistd logging in a .tac application</a></li><li><a href="#auto7">Services provided by Twisted</a></li><li><a href="#auto8">Service Collection</a></li></ul></ol></div>
14
<h2>Introduction<a name="auto0"/></h2>
16
<h3>Audience<a name="auto1"/></h3>
18
<p>The target audience of this document is a Twisted user who wants to deploy a
19
significant amount of Twisted code in a re-usable, standard and easily
20
configurable fashion. A Twisted user who wishes to use the Application
21
framework needs to be familiar with developing Twisted <a href="servers.html" shape="rect">servers</a> and/or <a href="clients.html" shape="rect">clients</a>.</p>
23
<h3>Goals<a name="auto2"/></h3>
26
<li>To introduce the Twisted Application infrastructure.</li>
28
<li>To explain how to deploy your Twisted application using <code>.tac</code>
29
files and <code>twistd</code></li>
31
<li>To outline the existing Twisted services.</li>
34
<h2>Overview<a name="auto3"/></h2>
36
<p>The Twisted Application infrastructure takes care of running and stopping
37
your application. Using this infrastructure frees you from from having to
38
write a large amount of boilerplate code by hooking your application into
39
existing tools that manage daemonization, logging, <a href="choosing-reactor.html" shape="rect">choosing a reactor</a> and more.</p>
41
<p>The major tool that manages Twisted applications is a command-line utility
42
called <code>twistd</code>. <code>twistd</code> is cross platform, and is the
43
recommended tool for running Twisted applications. </p>
46
<p>The core component of the Twisted Application infrastructure is the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.Application.html" title="twisted.application.service.Application">twisted.application.service.Application</a></code> object — an
47
object which represents your application. However, Application doesn't provide
48
anything that you'd want to manipulate directly. Instead, Application acts as
49
a container of any <q>Services</q> (objects implementing <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IService.html" title="twisted.application.service.IService">IService</a></code>) that your application
50
provides. Most of your interaction with the Application infrastructure will be
51
done through Services.</p>
53
<p>By <q>Service</q>, we mean anything in your application that can be started
54
and stopped. Typical services include web servers, FTP servers and SSH
55
clients. Your Application object can contain many services, and can even
56
contain structured hierarchies of Services using <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IServiceCollection.html" title="twisted.application.service.IServiceCollection">IServiceCollection</a></code>s.</p>
58
<p>Here's a simple example of constructing an Application object which
59
represents an echo server that runs on TCP port 7001.</p>
61
<pre class="python"><p class="py-linenumber"> 1
72
</p><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>, <span class="py-src-variable">service</span>
73
<span class="py-src-keyword">from</span> <span class="py-src-variable">somemodule</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">EchoFactory</span>
75
<span class="py-src-variable">port</span> = <span class="py-src-number">7001</span>
76
<span class="py-src-variable">factory</span> = <span class="py-src-variable">EchoFactory</span>()
78
<span class="py-src-comment"># this is the important bit</span>
79
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"echo"</span>) <span class="py-src-comment"># create the Application</span>
80
<span class="py-src-variable">echoService</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-variable">port</span>, <span class="py-src-variable">factory</span>) <span class="py-src-comment"># create the service</span>
81
<span class="py-src-comment"># add the service to the application</span>
82
<span class="py-src-variable">echoService</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
85
<p>See <a href="servers.html" shape="rect">Writing Servers</a> for an explanation of
88
<p>This example creates a simple hierarchy:
89
<pre xml:space="preserve">
93
</pre> More complicated hierarchies of services can be created using
94
IServiceCollection. You will most likely want to do this to manage Services
95
which are dependent on other Services. For example, a proxying Twisted
96
application might want its server Service to only start up after the associated
100
<h2>Using application<a name="auto4"/></h2>
102
<h3>twistd and tac<a name="auto5"/></h3><a name="twistd" shape="rect"/>
104
<p>To handle start-up and configuration of your Twisted application, the
105
Twisted Application infrastructure uses <code>.tac</code> files.
106
<code>.tac</code> are Python files which configure an <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.Application.html" title="twisted.application.service.Application">Application</a></code> object and assign this
107
object to the top-level variable <q><code>application</code></q>.</p>
109
<p>The following is a simple example of a <code>.tac</code> file:</p>
111
<div class="py-listing"><pre><p class="py-linenumber"> 1
145
</p><span class="py-src-comment"># You can run this .tac file directly with:</span>
146
<span class="py-src-comment"># twistd -ny service.tac</span>
148
<span class="py-src-string">"""
149
This is an example .tac file which starts a webserver on port 8080 and
150
serves files from the current working directory.
152
The important part of this, the part that makes it a .tac file, is
153
the final root-level section, which sets up the object called 'application'
154
which twistd will look for
155
"""</span>
157
<span class="py-src-keyword">import</span> <span class="py-src-variable">os</span>
158
<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">service</span>, <span class="py-src-variable">internet</span>
159
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">static</span>, <span class="py-src-variable">server</span>
161
<span class="py-src-keyword">def</span> <span class="py-src-identifier">getWebService</span>():
162
<span class="py-src-string">"""
163
Return a service suitable for creating an application object.
165
This service is a simple web server that serves files on port 8080 from
166
underneath the current working directory.
167
"""</span>
168
<span class="py-src-comment"># create a resource to serve static files</span>
169
<span class="py-src-variable">fileServer</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">static</span>.<span class="py-src-variable">File</span>(<span class="py-src-variable">os</span>.<span class="py-src-variable">getcwd</span>()))
170
<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-number">8080</span>, <span class="py-src-variable">fileServer</span>)
172
<span class="py-src-comment"># this is the core part of any tac file, the creation of the root-level</span>
173
<span class="py-src-comment"># application object</span>
174
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"Demo application"</span>)
176
<span class="py-src-comment"># attach the service to its parent application</span>
177
<span class="py-src-variable">service</span> = <span class="py-src-variable">getWebService</span>()
178
<span class="py-src-variable">service</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
179
</pre><div class="caption">Source listing - <a href="listings/application/service.tac"><span class="filename">listings/application/service.tac</span></a></div></div>
181
<p><code>twistd</code> is a program that runs Twisted applications using a
182
<code>.tac</code> file. In its most simple form, it takes a single argument
183
<code>-y</code> and a tac file name. For example, you can run the above server
184
with the command <code class="shell">twistd -y service.tac</code>.</p>
186
<p>By default, <code>twistd</code> daemonizes and logs to a file called
187
<code>twistd.log</code>. More usually, when debugging, you will want your
188
application to run in the foreground and log to the command line. To run the
189
above file like this, use the command <code class="shell">twistd -noy
190
service.tac</code></p>
192
<p>For more information, see the <code>twistd</code> man page.</p>
194
<h3>Customizing <code>twistd</code> logging in a .tac application<a name="auto6"/></h3>
197
The logging behavior can be customized through an API
198
accessible from <code>.tac</code> files. The <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.python.log.ILogObserver.html" title="twisted.python.log.ILogObserver">ILogObserver</a></code> component can be
199
set on an Application in order to customize the default log observer that
200
<code>twistd</code> will use.
204
Here is an example of how to use <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.python.logfile.DailyLogFile.html" title="twisted.python.logfile.DailyLogFile">DailyLogFile</a></code>, which rotates the log once
208
<pre class="python"><p class="py-linenumber">1
215
</p><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">Application</span>
216
<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-variable">log</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">ILogObserver</span>, <span class="py-src-variable">FileLogObserver</span>
217
<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-variable">logfile</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">DailyLogFile</span>
219
<span class="py-src-variable">application</span> = <span class="py-src-variable">Application</span>(<span class="py-src-string">"myapp"</span>)
220
<span class="py-src-variable">logfile</span> = <span class="py-src-variable">DailyLogFile</span>(<span class="py-src-string">"my.log"</span>, <span class="py-src-string">"/tmp"</span>)
221
<span class="py-src-variable">application</span>.<span class="py-src-variable">setComponent</span>(<span class="py-src-variable">ILogObserver</span>, <span class="py-src-variable">FileLogObserver</span>(<span class="py-src-variable">logfile</span>).<span class="py-src-variable">emit</span>)
225
invoking <code class="shell">twistd -y my.tac</code> will create a log file
226
at<code>/tmp/my.log</code>.
229
<h3>Services provided by Twisted<a name="auto7"/></h3>
231
<p>Twisted provides several services that you want to know about.</p>
233
<p>Each of these services (except TimerService) has a corresponding
234
<q>connect</q> or <q>listen</q> method on the reactor, and the constructors for
235
the services take the same arguments as the reactor methods. The
236
<q>connect</q> methods are for clients and the <q>listen</q> methods are for
237
servers. For example, TCPServer corresponds to reactor.listenTCP and TCPClient
238
corresponds to reactor.connectTCP. </p>
241
<dt><code>TCPServer</code>
244
<dt><code>TCPClient</code>
248
Services which allow you to make connections and listen for connections
251
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorTCP.listenTCP.html" title="twisted.internet.interfaces.IReactorTCP.listenTCP">listenTCP</a></code></li>
252
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorTCP.connectTCP.html" title="twisted.internet.interfaces.IReactorTCP.connectTCP">connectTCP</a></code></li>
256
<dt><code>UNIXServer</code></dt>
258
<dt><code>UNIXClient</code></dt>
261
Services which listen and make connections over UNIX sockets.
263
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUNIX.listenUNIX.html" title="twisted.internet.interfaces.IReactorUNIX.listenUNIX">listenUNIX</a></code></li>
264
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUNIX.connectUNIX.html" title="twisted.internet.interfaces.IReactorUNIX.connectUNIX">connectUNIX</a></code></li>
268
<dt><code>SSLServer</code></dt>
270
<dt><code>SSLClient</code></dt>
272
<dd>Services which allow you to make SSL connections and run SSL servers.
274
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorSSL.listenSSL.html" title="twisted.internet.interfaces.IReactorSSL.listenSSL">listenSSL</a></code></li>
275
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorSSL.connectSSL.html" title="twisted.internet.interfaces.IReactorSSL.connectSSL">connectSSL</a></code></li>
279
<dt><code>UDPServer</code></dt>
281
<dt><code>UDPClient</code></dt>
283
<dd>Services which allow you to send and receive data over UDP
285
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUDP.listenUDP.html" title="twisted.internet.interfaces.IReactorUDP.listenUDP">listenUDP</a></code></li>
288
<p>See also the <a href="udp.html" shape="rect">UDP documentation</a>.</p>
291
<dt><code>UNIXDatagramServer</code></dt>
293
<dt><code>UNIXDatagramClient</code></dt>
295
<dd>Services which send and receive data over UNIX datagram sockets.
297
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUDP.listenUNIXDatagram.html" title="twisted.internet.interfaces.IReactorUDP.listenUNIXDatagram">listenUNIXDatagram</a></code></li>
298
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUDP.connectUNIXDatagram.html" title="twisted.internet.interfaces.IReactorUDP.connectUNIXDatagram">connectUNIXDatagram</a></code></li>
302
<dt><code>MulticastServer</code></dt>
305
A server for UDP socket methods that support multicast.
307
<li><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorUDP.listenMulticast.html" title="twisted.internet.interfaces.IReactorUDP.listenMulticast">listenMulticast</a></code></li>
311
<dt><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.internet.TimerService.html" title="twisted.application.internet.TimerService">TimerService</a></code></dt>
314
A service to periodically call a function.
319
<h3>Service Collection<a name="auto8"/></h3>
321
<p><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IServiceCollection.html" title="twisted.application.service.IServiceCollection">IServiceCollection</a></code> objects contain
322
<code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IService.html" title="twisted.application.service.IService">IService</a></code> objects.
323
IService objects can be added to IServiceCollection by calling <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IService.setServiceParent.html" title="twisted.application.service.IService.setServiceParent">setServiceParent</a></code> and detached
324
by using <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IService.disownServiceParent.html" title="twisted.application.service.IService.disownServiceParent">disownServiceParent</a></code>.</p>
326
<p>The standard implementation of IServiceCollection is <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.MultiService.html" title="twisted.application.service.MultiService">MultiService</a></code>, which also implements
327
IService. MultiService is useful for creating a new Service which combines two
328
or more existing Services. For example, you could create a DNS Service as a
329
MultiService which has a TCP and a UDP Service as children.</p>
331
<pre class="python"><p class="py-linenumber"> 1
350
</p><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>, <span class="py-src-variable">service</span>
351
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">names</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">server</span>, <span class="py-src-variable">dns</span>, <span class="py-src-variable">hosts</span>
353
<span class="py-src-variable">port</span> = <span class="py-src-number">53</span>
355
<span class="py-src-comment"># Create a MultiService, and hook up a TCPServer and a UDPServer to it as</span>
356
<span class="py-src-comment"># children.</span>
357
<span class="py-src-variable">dnsService</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">MultiService</span>()
358
<span class="py-src-variable">hostsResolver</span> = <span class="py-src-variable">hosts</span>.<span class="py-src-variable">Resolver</span>(<span class="py-src-string">'/etc/hosts'</span>)
359
<span class="py-src-variable">tcpFactory</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">DNSServerFactory</span>([<span class="py-src-variable">hostsResolver</span>])
360
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-variable">port</span>, <span class="py-src-variable">tcpFactory</span>).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">dnsService</span>)
361
<span class="py-src-variable">udpFactory</span> = <span class="py-src-variable">dns</span>.<span class="py-src-variable">DNSDatagramProtocol</span>(<span class="py-src-variable">tcpFactory</span>)
362
<span class="py-src-variable">internet</span>.<span class="py-src-variable">UDPServer</span>(<span class="py-src-variable">port</span>, <span class="py-src-variable">udpFactory</span>).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">dnsService</span>)
364
<span class="py-src-comment"># Create an application as normal</span>
365
<span class="py-src-variable">application</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">Application</span>(<span class="py-src-string">"DNSExample"</span>)
367
<span class="py-src-comment"># Connect our MultiService to the application, just like a normal service.</span>
368
<span class="py-src-variable">dnsService</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
373
<p><a href="index.html">Index</a></p>
374
<span class="version">Version: 10.0.0</span>
b'\\ No newline at end of file'