~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/tutorial/library.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: The Evolution of Finger: making a finger library</title>
 
4
<link href="../stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">The Evolution of Finger: making a finger library</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Organization</a></li><li><a href="#auto2">Easy Configuration</a></li></ol></div>
 
10
    <div class="content">
 
11
 
 
12
<span/>
 
13
 
 
14
<h2>Introduction<a name="auto0"/></h2>
 
15
 
 
16
<p> This is the tenth part of the Twisted tutorial <a href="index.html" shape="rect">Twisted from Scratch, or The Evolution of Finger</a>.</p>
 
17
 
 
18
<p>In this part, we separate the application code that launches a finger service
 
19
from the library code which defines a finger service, placing the application in
 
20
a Twisted Application Configuration (.tac) file. We also move configuration
 
21
(such as HTML templates) into separate files. Configuration and deployment with
 
22
.tac and twistd are introduced in <a href="../application.html" shape="rect">Using the
 
23
Twisted Application Framework</a>.</p>
 
24
 
 
25
<h2>Organization<a name="auto1"/></h2>
 
26
 
 
27
<p>Now this code, while quite modular and well-designed, isn't
 
28
properly organized. Everything above the <code>application=</code> belongs in a
 
29
module, and the HTML templates all belong in separate files.
 
30
</p>
 
31
 
 
32
<p>We can use the templateFile and templateDirectory attributes to indicate
 
33
what HTML template file to use for each Page, and where to look for it.</p>
 
34
 
 
35
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
36
 2
 
37
 3
 
38
 4
 
39
 5
 
40
 6
 
41
 7
 
42
 8
 
43
 9
 
44
10
 
45
11
 
46
12
 
47
13
 
48
14
 
49
15
 
50
16
 
51
17
 
52
18
 
53
19
 
54
20
 
55
21
 
56
22
 
57
23
 
58
24
 
59
25
 
60
26
 
61
27
 
62
28
 
63
29
 
64
30
 
65
31
 
66
</p><span class="py-src-comment"># organized-finger.tac</span>
 
67
<span class="py-src-comment"># eg:  twistd -ny organized-finger.tac</span>
 
68
 
 
69
<span class="py-src-keyword">import</span> <span class="py-src-variable">finger</span>
 
70
 
 
71
<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">protocol</span>, <span class="py-src-variable">reactor</span>, <span class="py-src-variable">defer</span>
 
72
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">spread</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">pb</span>
 
73
<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">resource</span>, <span class="py-src-variable">server</span>
 
74
<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>, <span class="py-src-variable">strports</span>
 
75
<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">log</span>
 
76
 
 
77
<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">'finger'</span>, <span class="py-src-variable">uid</span>=<span class="py-src-number">1</span>, <span class="py-src-variable">gid</span>=<span class="py-src-number">1</span>)
 
78
<span class="py-src-variable">f</span> = <span class="py-src-variable">finger</span>.<span class="py-src-variable">FingerService</span>(<span class="py-src-string">'/etc/users'</span>)
 
79
<span class="py-src-variable">serviceCollection</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">IServiceCollection</span>(<span class="py-src-variable">application</span>)
 
80
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">79</span>, <span class="py-src-variable">finger</span>.<span class="py-src-variable">IFingerFactory</span>(<span class="py-src-variable">f</span>)
 
81
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
82
 
 
83
<span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>(<span class="py-src-variable">f</span>))
 
84
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">8000</span>, <span class="py-src-variable">site</span>
 
85
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
86
 
 
87
<span class="py-src-variable">internet</span>.<span class="py-src-variable">SSLServer</span>(<span class="py-src-number">443</span>, <span class="py-src-variable">site</span>, <span class="py-src-variable">finger</span>.<span class="py-src-variable">ServerContextFactory</span>()
 
88
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
89
 
 
90
<span class="py-src-variable">i</span> = <span class="py-src-variable">finger</span>.<span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
 
91
<span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-string">'fingerbot'</span>
 
92
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPClient</span>(<span class="py-src-string">'irc.freenode.org'</span>, <span class="py-src-number">6667</span>, <span class="py-src-variable">i</span>
 
93
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
94
 
 
95
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">8889</span>, <span class="py-src-variable">pb</span>.<span class="py-src-variable">PBServerFactory</span>(<span class="py-src-variable">finger</span>.<span class="py-src-variable">IPerspectiveFinger</span>(<span class="py-src-variable">f</span>))
 
96
                   ).<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">serviceCollection</span>)
 
97
</pre><div class="caption">Source listing - <a href="listings/finger/organized-finger.tac"><span class="filename">listings/finger/organized-finger.tac</span></a></div></div>
 
98
 
 
99
<p>
 
100
Note that our program is now quite separated. We have:
 
101
<ul>
 
102
  <li>Code (in the module)</li>
 
103
  <li>Configuration (file above)</li>
 
104
  <li>Presentation (templates)</li>
 
105
  <li>Content (/etc/users)</li>
 
106
  <li>Deployment (twistd)</li>
 
107
</ul>
 
108
 
 
109
Prototypes don't need this level of separation, so our earlier examples all
 
110
bunched together. However, real applications do. Thankfully, if we write our
 
111
code correctly, it is easy to achieve a good separation of parts.
 
112
</p>
 
113
 
 
114
 
 
115
<h2>Easy Configuration<a name="auto2"/></h2>
 
116
 
 
117
<p>We can also supply easy configuration for common cases with a makeService method that will also help build .tap files later:</p>
 
118
 
 
119
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
120
 2
 
121
 3
 
122
 4
 
123
 5
 
124
 6
 
125
 7
 
126
 8
 
127
 9
 
128
10
 
129
11
 
130
12
 
131
13
 
132
14
 
133
15
 
134
16
 
135
17
 
136
18
 
137
19
 
138
20
 
139
21
 
140
22
 
141
23
 
142
24
 
143
25
 
144
26
 
145
27
 
146
28
 
147
29
 
148
30
 
149
31
 
150
32
 
151
33
 
152
34
 
153
35
 
154
36
 
155
37
 
156
38
 
157
</p><span class="py-src-comment"># Easy configuration</span>
 
158
<span class="py-src-comment"># makeService from finger module</span>
 
159
 
 
160
<span class="py-src-keyword">def</span> <span class="py-src-identifier">makeService</span>(<span class="py-src-parameter">config</span>):
 
161
    <span class="py-src-comment"># finger on port 79</span>
 
162
    <span class="py-src-variable">s</span> = <span class="py-src-variable">service</span>.<span class="py-src-variable">MultiService</span>()
 
163
    <span class="py-src-variable">f</span> = <span class="py-src-variable">FingerService</span>(<span class="py-src-variable">config</span>[<span class="py-src-string">'file'</span>])
 
164
    <span class="py-src-variable">h</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">79</span>, <span class="py-src-variable">IFingerFactory</span>(<span class="py-src-variable">f</span>))
 
165
    <span class="py-src-variable">h</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
 
166
 
 
167
    <span class="py-src-comment"># website on port 8000</span>
 
168
    <span class="py-src-variable">r</span> = <span class="py-src-variable">resource</span>.<span class="py-src-variable">IResource</span>(<span class="py-src-variable">f</span>)
 
169
    <span class="py-src-variable">r</span>.<span class="py-src-variable">templateDirectory</span> = <span class="py-src-variable">config</span>[<span class="py-src-string">'templates'</span>]
 
170
    <span class="py-src-variable">site</span> = <span class="py-src-variable">server</span>.<span class="py-src-variable">Site</span>(<span class="py-src-variable">r</span>)
 
171
    <span class="py-src-variable">j</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">8000</span>, <span class="py-src-variable">site</span>)
 
172
    <span class="py-src-variable">j</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
 
173
 
 
174
    <span class="py-src-comment"># ssl on port 443</span>
 
175
    <span class="py-src-keyword">if</span> <span class="py-src-variable">config</span>.<span class="py-src-variable">get</span>(<span class="py-src-string">'ssl'</span>):
 
176
        <span class="py-src-variable">k</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">SSLServer</span>(<span class="py-src-number">443</span>, <span class="py-src-variable">site</span>, <span class="py-src-variable">ServerContextFactory</span>())
 
177
        <span class="py-src-variable">k</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
 
178
 
 
179
    <span class="py-src-comment"># irc fingerbot</span>
 
180
    <span class="py-src-keyword">if</span> <span class="py-src-variable">config</span>.<span class="py-src-variable">has_key</span>(<span class="py-src-string">'ircnick'</span>):
 
181
        <span class="py-src-variable">i</span> = <span class="py-src-variable">IIRCClientFactory</span>(<span class="py-src-variable">f</span>)
 
182
        <span class="py-src-variable">i</span>.<span class="py-src-variable">nickname</span> = <span class="py-src-variable">config</span>[<span class="py-src-string">'ircnick'</span>]
 
183
        <span class="py-src-variable">ircserver</span> = <span class="py-src-variable">config</span>[<span class="py-src-string">'ircserver'</span>]
 
184
        <span class="py-src-variable">b</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPClient</span>(<span class="py-src-variable">ircserver</span>, <span class="py-src-number">6667</span>, <span class="py-src-variable">i</span>)
 
185
        <span class="py-src-variable">b</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
 
186
 
 
187
    <span class="py-src-comment"># Pespective Broker on port 8889</span>
 
188
    <span class="py-src-keyword">if</span> <span class="py-src-variable">config</span>.<span class="py-src-variable">has_key</span>(<span class="py-src-string">'pbport'</span>):
 
189
        <span class="py-src-variable">m</span> = <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(
 
190
            <span class="py-src-variable">int</span>(<span class="py-src-variable">config</span>[<span class="py-src-string">'pbport'</span>]),
 
191
            <span class="py-src-variable">pb</span>.<span class="py-src-variable">PBServerFactory</span>(<span class="py-src-variable">IPerspectiveFinger</span>(<span class="py-src-variable">f</span>)))
 
192
        <span class="py-src-variable">m</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">s</span>)
 
193
 
 
194
    <span class="py-src-keyword">return</span> <span class="py-src-variable">s</span>
 
195
</pre><div class="caption">Source listing - <a href="listings/finger/finger_config.py"><span class="filename">listings/finger/finger_config.py</span></a></div></div>
 
196
 
 
197
<p>And we can write simpler files now:</p>
 
198
 
 
199
<div class="py-listing"><pre><p class="py-linenumber"> 1
 
200
 2
 
201
 3
 
202
 4
 
203
 5
 
204
 6
 
205
 7
 
206
 8
 
207
 9
 
208
10
 
209
11
 
210
12
 
211
13
 
212
14
 
213
15
 
214
16
 
215
17
 
216
</p><span class="py-src-comment"># simple-finger.tac</span>
 
217
<span class="py-src-comment"># eg:  twistd -ny simple-finger.tac</span>
 
218
 
 
219
<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>
 
220
 
 
221
<span class="py-src-keyword">import</span> <span class="py-src-variable">finger</span>
 
222
 
 
223
<span class="py-src-variable">options</span> = { <span class="py-src-string">'file'</span>: <span class="py-src-string">'/etc/users'</span>,
 
224
            <span class="py-src-string">'templates'</span>: <span class="py-src-string">'/usr/share/finger/templates'</span>,
 
225
            <span class="py-src-string">'ircnick'</span>: <span class="py-src-string">'fingerbot'</span>,
 
226
            <span class="py-src-string">'ircserver'</span>: <span class="py-src-string">'irc.freenode.net'</span>,
 
227
            <span class="py-src-string">'pbport'</span>: <span class="py-src-number">8889</span>,
 
228
            <span class="py-src-string">'ssl'</span>: <span class="py-src-string">'ssl=0'</span> }
 
229
 
 
230
<span class="py-src-variable">ser</span> = <span class="py-src-variable">finger</span>.<span class="py-src-variable">makeService</span>(<span class="py-src-variable">options</span>)
 
231
<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">'finger'</span>, <span class="py-src-variable">uid</span>=<span class="py-src-number">1</span>, <span class="py-src-variable">gid</span>=<span class="py-src-number">1</span>)
 
232
<span class="py-src-variable">ser</span>.<span class="py-src-variable">setServiceParent</span>(<span class="py-src-variable">service</span>.<span class="py-src-variable">IServiceCollection</span>(<span class="py-src-variable">application</span>))
 
233
</pre><div class="caption">Source listing - <a href="listings/finger/simple-finger.tac"><span class="filename">listings/finger/simple-finger.tac</span></a></div></div>
 
234
 
 
235
<pre class="shell" xml:space="preserve">
 
236
% twisted -ny simple-finger.tac
 
237
</pre>
 
238
 
 
239
 
 
240
<p>Note: the finger <em>user</em> still has ultimate power: he can use
 
241
makeService, or he can use the lower-level interface if he has
 
242
specific needs (maybe an IRC server on some other port? maybe we
 
243
want the non-SSL webserver to listen only locally?  etc. etc.)
 
244
This is an important design principle: never force a layer of abstraction:
 
245
allow usage of layers of abstractions.</p>
 
246
 
 
247
<p>The pasta theory of design:</p>
 
248
 
 
249
<ul>
 
250
<li>Spaghetti: each piece of code interacts with every other piece of
 
251
    code [can be implemented with GOTO, functions, objects]</li>
 
252
<li>Lasagna: code has carefully designed layers. Each layer is, in
 
253
    theory independent. However low-level layers usually cannot be
 
254
    used easily, and high-level layers depend on low-level layers.</li>
 
255
<li>Ravioli: each part of the code is useful by itself. There is a thin
 
256
    layer of interfaces between various parts [the sauce]. Each part
 
257
    can be usefully be used elsewhere.</li>
 
258
<li>...but sometimes, the user just wants to order <q>Ravioli</q>, so one
 
259
    coarse-grain easily definable layer of abstraction on top of it all
 
260
    can be useful.</li>
 
261
</ul>
 
262
 
 
263
 
 
264
</div>
 
265
 
 
266
    <p><a href="../index.html">Index</a></p>
 
267
    <span class="version">Version: 10.0.0</span>
 
268
  </body>
 
269
</html>
 
 
b'\\ No newline at end of file'