Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / web / howto / web-in-60 / wsgi.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: WSGI</title>
4 <link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
5   </head>
6
7   <body bgcolor="white">
8     <h1 class="title">WSGI</h1>
9     <div class="toc"><ol/></div>
10     <div class="content">
11 <span/>
12
13 <p>The goal of this example is to show you how to
14 use <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.web.wsgi.WSGIResource.html" title="twisted.web.wsgi.WSGIResource">WSGIResource</a></code>,
15 another existing <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.web.resource.Resource.html" title="twisted.web.resource.Resource">Resource</a></code> subclass, to
16 serve <a href="http://www.python.org/dev/peps/pep-0333/" shape="rect">WSGI applications</a>
17 in a Twisted Web server.</p>
18
19 <p>Note that <code>WSGIResource</code> is a multithreaded WSGI container. Like
20 any other WSGI container, you can't do anything asynchronous in your WSGI
21 applications, even though this is a Twisted WSGI container.</p>
22
23 <p>The first new thing in this example is the import
24 of <code>WSGIResource</code>:</p>
25
26 <pre class="python"><p class="py-linenumber">1
27 </p><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-variable">wsgi</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">WSGIResource</span>
28 </pre>
29
30 <p>Nothing too surprising there. We still need one of the other usual suspects,
31 too:</p>
32
33 <pre class="python"><p class="py-linenumber">1
34 </p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
35 </pre>
36
37 <p>You'll see why in a minute. Next, we need a WSGI application. Here's a really
38 simple one just to get things going:</p>
39
40 <pre class="python"><p class="py-linenumber">1
41 2
42 3
43 </p><span class="py-src-keyword">def</span> <span class="py-src-identifier">application</span>(<span class="py-src-parameter">environ</span>, <span class="py-src-parameter">start_response</span>):
44     <span class="py-src-variable">start_response</span>(<span class="py-src-string">'200 OK'</span>, [(<span class="py-src-string">'Content-type'</span>, <span class="py-src-string">'text/plain'</span>)])
45     <span class="py-src-keyword">return</span> [<span class="py-src-string">'Hello, world!'</span>]
46 </pre>
47
48 <p>If this doesn't make sense to you, take a look at one of
49 these <a href="http://wsgi.org/wsgi/Learn_WSGI" shape="rect">fine tutorials</a>. Otherwise,
50 or once you're done with that, the next step is to create
51 a <code>WSGIResource</code> instance, as this is going to be
52 another <a href="rpy-scripts.html" shape="rect">rpy script</a> example:</p>
53
54 <pre class="python"><p class="py-linenumber">1
55 </p><span class="py-src-variable">resource</span> = <span class="py-src-variable">WSGIResource</span>(<span class="py-src-variable">reactor</span>, <span class="py-src-variable">reactor</span>.<span class="py-src-variable">getThreadPool</span>(), <span class="py-src-variable">application</span>)
56 </pre>
57
58 <p>Let's dwell on this line for a minute. The first parameter passed
59 to <code>WSGIResource</code> is the reactor. Despite the fact that the
60 reactor is global and any code that wants it can always just import it
61 (as, in fact, this rpy script simply does itself), passing it around
62 as a parameter leaves the door open for certain future possibilities -
63 for example, having more than one reactor. There are also testing
64 implications. Consider how much easier it is to unit test a function
65 that accepts a reactor - perhaps a mock reactor specially constructed
66 to make your tests easy to write - rather than importing the real
67 global reactor. That's why <code>WSGIResource</code> requires you to
68 pass the reactor to it.</p>
69
70 <p>The second parameter passed to <code>WSGIResource</code> is
71 a <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.python.threadpool.ThreadPool.html" title="twisted.python.threadpool.ThreadPool">ThreadPool</a></code>. <code>WSGIResource</code>
72 uses this to actually call the application object passed in to it. To keep this
73 example short, we're passing in the reactor's internal threadpool here, letting
74 us skip its creation and shutdown-time destruction. For finer control over how
75 many WSGI requests are served in parallel, you may want to create your own
76 thread pool to use with your <code>WSGIResource</code>, but for simple testing,
77 using the reactor's is fine.</p>
78
79 <p>The final argument is the application object. This is pretty typical of how
80 WSGI containers work.</p>
81
82 <p>The example, sans interruption:</p>
83
84 <pre class="python"><p class="py-linenumber">1
85 2
86 3
87 4
88 5
89 6
90 7
91 8
92 </p><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-variable">wsgi</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">WSGIResource</span>
93 <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>
94
95 <span class="py-src-keyword">def</span> <span class="py-src-identifier">application</span>(<span class="py-src-parameter">environ</span>, <span class="py-src-parameter">start_response</span>):
96     <span class="py-src-variable">start_response</span>(<span class="py-src-string">'200 OK'</span>, [(<span class="py-src-string">'Content-type'</span>, <span class="py-src-string">'text/plain'</span>)])
97     <span class="py-src-keyword">return</span> [<span class="py-src-string">'Hello, world!'</span>]
98
99 <span class="py-src-variable">resource</span> = <span class="py-src-variable">WSGIResource</span>(<span class="py-src-variable">reactor</span>, <span class="py-src-variable">reactor</span>.<span class="py-src-variable">getThreadPool</span>(), <span class="py-src-variable">application</span>)
100 </pre>
101
102 <p>Up to the point where the <code>WSGIResource</code> instance defined here
103 exists in the resource hierarchy, the normal resource traversal rules
104 apply: <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.web.resource.Resource.getChild.html" title="twisted.web.resource.Resource.getChild">getChild</a></code>
105 will be called to handle each segment. Once the <code>WSGIResource</code> is
106 encountered, though, that process stops and all further URL handling is the
107 responsibility of the WSGI application. This application does nothing with the
108 URL, though, so you won't be able to tell that.</p>
109
110 <p>Oh, and as was the case with the first static file example, there's also a
111 command line option you can use to avoid a lot of this. If you just put the
112 above application function, without all of the <code>WSGIResource</code> stuff,
113 into a file, say, <code>foo.py</code>, then you can launch a roughly equivalent
114 server like this:</p>
115
116 <pre class="shell" xml:space="preserve">
117 $ twistd -n web --wsgi foo.application
118 </pre>
119
120 </div>
121
122     <p><a href="../index.html">Index</a></p>
123     <span class="version">Version: 12.1.0</span>
124   </body>
125 </html>