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</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/12.1.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/12.1.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/12.1.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/12.1.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<a name="auto6"/></h3>
197 <code>twistd</code> logging can be customized using the command
198 line. This requires that a <em>log observer factory</em> be
199 importable. Given a file named <code>my.py</code> with the code:
202 <pre class="python"><p class="py-linenumber">1
206 </p><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">FileLogObserver</span>
208 <span class="py-src-keyword">def</span> <span class="py-src-identifier">logger</span>():
209 <span class="py-src-keyword">return</span> <span class="py-src-variable">FileLogObserver</span>(<span class="py-src-variable">open</span>(<span class="py-src-string">"/tmp/my.log"</span>, <span class="py-src-string">"w"</span>)).<span class="py-src-variable">emit</span>
213 invoking <code class="shell">twistd --logger my.logger ...</code> will log
214 to a file named <code>/tmp/my.log</code> (this simple example could easily be
215 replaced with use of the <code>--logfile</code> parameter to twistd).
219 Alternatively, the logging behavior can be customized through an API
220 accessible from <code>.tac</code> files. The <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.python.log.ILogObserver.html" title="twisted.python.log.ILogObserver">ILogObserver</a></code> component can be
221 set on an Application in order to customize the default log observer that
222 <code>twistd</code> will use.
226 Here is an example of how to use <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.python.logfile.DailyLogFile.html" title="twisted.python.logfile.DailyLogFile">DailyLogFile</a></code>, which rotates the log once
230 <pre class="python"><p class="py-linenumber">1
237 </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>
238 <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>
239 <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>
241 <span class="py-src-variable">application</span> = <span class="py-src-variable">Application</span>(<span class="py-src-string">"myapp"</span>)
242 <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>)
243 <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>)
247 invoking <code class="shell">twistd -y my.tac</code> will create a log file
248 at <code>/tmp/my.log</code>.
251 <h3>Services provided by Twisted<a name="auto7"/></h3>
253 <p>Twisted provides several services that you want to know about.</p>
255 <p>Each of these services (except TimerService) has a corresponding
256 <q>connect</q> or <q>listen</q> method on the reactor, and the constructors for
257 the services take the same arguments as the reactor methods. The
258 <q>connect</q> methods are for clients and the <q>listen</q> methods are for
259 servers. For example, TCPServer corresponds to reactor.listenTCP and TCPClient
260 corresponds to reactor.connectTCP. </p>
263 <dt><code>TCPServer</code>
266 <dt><code>TCPClient</code>
270 Services which allow you to make connections and listen for connections
273 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorTCP.listenTCP.html" title="twisted.internet.interfaces.IReactorTCP.listenTCP">listenTCP</a></code></li>
274 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorTCP.connectTCP.html" title="twisted.internet.interfaces.IReactorTCP.connectTCP">connectTCP</a></code></li>
278 <dt><code>UNIXServer</code></dt>
280 <dt><code>UNIXClient</code></dt>
283 Services which listen and make connections over UNIX sockets.
285 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorUNIX.listenUNIX.html" title="twisted.internet.interfaces.IReactorUNIX.listenUNIX">listenUNIX</a></code></li>
286 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorUNIX.connectUNIX.html" title="twisted.internet.interfaces.IReactorUNIX.connectUNIX">connectUNIX</a></code></li>
290 <dt><code>SSLServer</code></dt>
292 <dt><code>SSLClient</code></dt>
294 <dd>Services which allow you to make SSL connections and run SSL servers.
296 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorSSL.listenSSL.html" title="twisted.internet.interfaces.IReactorSSL.listenSSL">listenSSL</a></code></li>
297 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorSSL.connectSSL.html" title="twisted.internet.interfaces.IReactorSSL.connectSSL">connectSSL</a></code></li>
301 <dt><code>UDPServer</code></dt>
303 <dt><code>UDPClient</code></dt>
305 <dd>Services which allow you to send and receive data over UDP
307 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorUDP.listenUDP.html" title="twisted.internet.interfaces.IReactorUDP.listenUDP">listenUDP</a></code></li>
310 <p>See also the <a href="udp.html" shape="rect">UDP documentation</a>.</p>
313 <dt><code>UNIXDatagramServer</code></dt>
315 <dt><code>UNIXDatagramClient</code></dt>
317 <dd>Services which send and receive data over UNIX datagram sockets.
319 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorUNIXDatagram.listenUNIXDatagram.html" title="twisted.internet.interfaces.IReactorUNIXDatagram.listenUNIXDatagram">listenUNIXDatagram</a></code></li>
320 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorUNIXDatagram.connectUNIXDatagram.html" title="twisted.internet.interfaces.IReactorUNIXDatagram.connectUNIXDatagram">connectUNIXDatagram</a></code></li>
324 <dt><code>MulticastServer</code></dt>
327 A server for UDP socket methods that support multicast.
329 <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.interfaces.IReactorMulticast.listenMulticast.html" title="twisted.internet.interfaces.IReactorMulticast.listenMulticast">listenMulticast</a></code></li>
333 <dt><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.internet.TimerService.html" title="twisted.application.internet.TimerService">TimerService</a></code></dt>
336 A service to periodically call a function.
341 <h3>Service Collection<a name="auto8"/></h3>
343 <p><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.service.IServiceCollection.html" title="twisted.application.service.IServiceCollection">IServiceCollection</a></code> objects contain
344 <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.service.IService.html" title="twisted.application.service.IService">IService</a></code> objects.
345 IService objects can be added to IServiceCollection by calling <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.service.IService.setServiceParent.html" title="twisted.application.service.IService.setServiceParent">setServiceParent</a></code> and detached
346 by using <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.service.IService.disownServiceParent.html" title="twisted.application.service.IService.disownServiceParent">disownServiceParent</a></code>.</p>
348 <p>The standard implementation of IServiceCollection is <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.application.service.MultiService.html" title="twisted.application.service.MultiService">MultiService</a></code>, which also implements
349 IService. MultiService is useful for creating a new Service which combines two
350 or more existing Services. For example, you could create a DNS Service as a
351 MultiService which has a TCP and a UDP Service as children.</p>
353 <pre class="python"><p class="py-linenumber"> 1
372 </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>
373 <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>
375 <span class="py-src-variable">port</span> = <span class="py-src-number">53</span>
377 <span class="py-src-comment"># Create a MultiService, and hook up a TCPServer and a UDPServer to it as</span>
378 <span class="py-src-comment"># children.</span>
379 <span class="py-src-variable">dnsService</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">MultiService</span>()
380 <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>)
381 <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>])
382 <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>)
383 <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>)
384 <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>)
386 <span class="py-src-comment"># Create an application as normal</span>
387 <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>)
389 <span class="py-src-comment"># Connect our MultiService to the application, just like a normal service.</span>
390 <span class="py-src-variable">dnsService</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">application</span>)
395 <p><a href="index.html">Index</a></p>
396 <span class="version">Version: 12.1.0</span>