Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / application.html
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">
2   <head>
3 <title>Twisted Documentation: Using the Twisted Application Framework</title>
4 <link href="stylesheet.css" rel="stylesheet" type="text/css"/>
5   </head>
6
7   <body bgcolor="white">
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>
10     <div class="content">
11
12 <span/>
13
14 <h2>Introduction<a name="auto0"/></h2>
15
16 <h3>Audience<a name="auto1"/></h3>
17
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>
22
23 <h3>Goals<a name="auto2"/></h3>
24
25 <ul>
26   <li>To introduce the Twisted Application infrastructure.</li>
27
28   <li>To explain how to deploy your Twisted application using <code>.tac</code>
29   files and <code>twistd</code></li>
30
31   <li>To outline the existing Twisted services.</li>
32 </ul>
33
34 <h2>Overview<a name="auto3"/></h2>
35
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>
40
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>
44
45
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>
52
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>
57
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>
60
61 <pre class="python"><p class="py-linenumber"> 1
62  2
63  3
64  4
65  5
66  6
67  7
68  8
69  9
70 10
71 11
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>
74
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>()
77
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">&quot;echo&quot;</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>)
83 </pre>
84
85 <p>See <a href="servers.html" shape="rect">Writing Servers</a> for an explanation of
86 EchoFactory.</p>
87
88 <p>This example creates a simple hierarchy:
89 <pre xml:space="preserve">
90    application
91    |
92    `- echoService
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
97 Client service. </p>
98
99
100 <h2>Using application<a name="auto4"/></h2>
101
102 <h3>twistd and tac<a name="auto5"/></h3><a name="twistd" shape="rect"/>
103
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>
108
109 <p>The following is a simple example of a <code>.tac</code> file:</p>
110
111 <div class="py-listing"><pre><p class="py-linenumber"> 1
112  2
113  3
114  4
115  5
116  6
117  7
118  8
119  9
120 10
121 11
122 12
123 13
124 14
125 15
126 16
127 17
128 18
129 19
130 20
131 21
132 22
133 23
134 24
135 25
136 26
137 27
138 28
139 29
140 30
141 31
142 32
143 33
144 34
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>
147
148 <span class="py-src-string">&quot;&quot;&quot;
149 This is an example .tac file which starts a webserver on port 8080 and
150 serves files from the current working directory.
151
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 &quot;&quot;&quot;</span>
156
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>
160
161 <span class="py-src-keyword">def</span> <span class="py-src-identifier">getWebService</span>():
162     <span class="py-src-string">&quot;&quot;&quot;
163     Return a service suitable for creating an application object.
164
165     This service is a simple web server that serves files on port 8080 from
166     underneath the current working directory.
167     &quot;&quot;&quot;</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>)
171
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">&quot;Demo application&quot;</span>)
175
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>
180
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>
185
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>
191
192 <p>For more information, see the <code>twistd</code> man page.</p>
193
194 <h3>Customizing <code>twistd</code> logging<a name="auto6"/></h3>
195
196 <p>
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:
200 </p>
201
202 <pre class="python"><p class="py-linenumber">1
203 2
204 3
205 4
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>
207
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">&quot;/tmp/my.log&quot;</span>, <span class="py-src-string">&quot;w&quot;</span>)).<span class="py-src-variable">emit</span>
210 </pre>
211
212 <p>
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).
216 </p>
217
218 <p>
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.
223 </p>
224
225 <p>
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
227 per day.
228 </p>
229
230 <pre class="python"><p class="py-linenumber">1
231 2
232 3
233 4
234 5
235 6
236 7
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>
240
241 <span class="py-src-variable">application</span> = <span class="py-src-variable">Application</span>(<span class="py-src-string">&quot;myapp&quot;</span>)
242 <span class="py-src-variable">logfile</span> = <span class="py-src-variable">DailyLogFile</span>(<span class="py-src-string">&quot;my.log&quot;</span>, <span class="py-src-string">&quot;/tmp&quot;</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>)
244 </pre>
245
246 <p>
247 invoking <code class="shell">twistd -y my.tac</code> will create a log file
248 at <code>/tmp/my.log</code>.
249 </p>
250
251 <h3>Services provided by Twisted<a name="auto7"/></h3>
252
253 <p>Twisted provides several services that you want to know about.</p>
254
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>
261
262 <dl>
263   <dt><code>TCPServer</code>
264   </dt>
265
266   <dt><code>TCPClient</code>
267   </dt>
268
269   <dd>
270     Services which allow you to make connections and listen for connections
271     on TCP ports.
272     <ul>
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>
275     </ul>
276   </dd>
277
278   <dt><code>UNIXServer</code></dt>
279
280   <dt><code>UNIXClient</code></dt>
281
282   <dd>
283     Services which listen and make connections over UNIX sockets.
284     <ul>
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>
287     </ul>
288   </dd>
289
290   <dt><code>SSLServer</code></dt>
291
292   <dt><code>SSLClient</code></dt>
293
294   <dd>Services which allow you to make SSL connections and run SSL servers.
295     <ul>
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>
298     </ul>
299   </dd>
300
301   <dt><code>UDPServer</code></dt>
302
303   <dt><code>UDPClient</code></dt>
304
305   <dd>Services which allow you to send and receive data over UDP
306     <ul>
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>
308     </ul>
309
310     <p>See also the <a href="udp.html" shape="rect">UDP documentation</a>.</p>
311   </dd>
312
313   <dt><code>UNIXDatagramServer</code></dt>
314
315   <dt><code>UNIXDatagramClient</code></dt>
316
317   <dd>Services which send and receive data over UNIX datagram sockets.
318     <ul>
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>
321     </ul>
322   </dd>
323
324   <dt><code>MulticastServer</code></dt>
325
326   <dd>
327     A server for UDP socket methods that support multicast.
328     <ul>
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>
330     </ul>
331   </dd>
332
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>
334
335   <dd>
336     A service to periodically call a function.
337   </dd>
338
339 </dl>
340
341 <h3>Service Collection<a name="auto8"/></h3>
342
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>
347
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>
352
353 <pre class="python"><p class="py-linenumber"> 1
354  2
355  3
356  4
357  5
358  6
359  7
360  8
361  9
362 10
363 11
364 12
365 13
366 14
367 15
368 16
369 17
370 18
371 19
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>
374
375 <span class="py-src-variable">port</span> = <span class="py-src-number">53</span>
376
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>)
385
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">&quot;DNSExample&quot;</span>)
388
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>)
391 </pre>
392
393 </div>
394
395     <p><a href="index.html">Index</a></p>
396     <span class="version">Version: 12.1.0</span>
397   </body>
398 </html>