Ticket #4569: tutorial2.xhtml.patch
| File tutorial2.xhtml.patch, 18.1 KB (added by jdb, 3 years ago) |
|---|
-
doc/core/howto/tutorial/intro.xhtml
diff -bu doc/core/howto/tutorial/intro.xhtml doc/core/howto/tutorial/intro.xhtml
27 27 No Plan. 28 28 </pre> 29 29 30 <p>If the target computer does not have the <code>fingerd</code> <a 31 href="../glossary.xhtml#Daemon">daemon</a> running you'll get a "Connection 32 Refused" error. Paranoid sysadmins keep <code>fingerd</code> off or limit the 33 output to hinder crackers and harassers. The above format is the standard 34 <code>fingerd</code> default, but an alternate implementation can output 35 anything it wants, such as automated responsibility status for everyone in an 36 organization. You can also define pseudo "users", which are essentially 37 keywords.</p> 30 <p>If the target computer does not have 31 the <code>fingerd</code> <a href="../glossary.xhtml#Daemon">daemon</a> 32 running you'll get a "Connection Refused" error. Paranoid sysadmins 33 keep <code>fingerd</code> off or limit the output to hinder crackers 34 and harassers. The above format is the standard <code>fingerd</code> 35 default, but an alternate implementation can output anything it wants, 36 such as automated responsibility status for everyone in an 37 organization. You can also define pseudo "users", which are 38 essentially keywords.</p> 38 39 39 40 <p>This portion of the tutorial makes use of factories and protocols as 40 41 introduced in the <a href="../servers.xhtml">Writing a TCP Server howto</a> and … … 75 76 over and over again, responding to network events and making scheduled calls to 76 77 code.</p> 77 78 78 <p>Note that there are actually several different reactors to choose from; 79 <code>from twisted.internet import reactor</code> returns the current reactor. 80 If you haven't chosen a reactor class yet, it automatically chooses the 81 default. See the <a href="../reactor-basics.xhtml">Reactor Basics HOWTO</a> 82 for more information.</p> 79 <p>Note that there are actually several different reactors to choose 80 from; <code>from twisted.internet import reactor</code> returns the 81 current reactor. If you haven't chosen a reactor class yet, it 82 automatically chooses the default. See 83 the <a href="../reactor-basics.xhtml">Reactor Basics HOWTO</a> for 84 more information.</p> 83 85 84 86 <h2>Do Nothing</h2> 85 87 … … 189 191 other operations in the meantime, and waits for some signal that data is ready 190 192 to be processed before returning to that process.</p> 191 193 192 <p>In brief, the code in <code>FingerFactory</code> above creates a Deferred, 193 to which we start to attach <em>callbacks</em>. The deferred action in 194 <code>FingerFactory</code> is actually a fast-running expression consisting of 195 one dictionary method, <code>get</code>. Since this action can execute without 196 delay, <code>FingerFactory.getUser</code> uses <code>defer.succeed</code> to 197 create a <code>Deferred</code> which already has a result, meaning its return 198 value will be passed immediately to the first callback function, which turns out 199 to be <code>FingerProtocol.writeResponse</code>. We've also defined an 200 <em>errback</em> (appropriately named <code>FingerProtocol.onError</code>) that 201 will be called instead of <code>writeResponse</code> if something goes 202 wrong.</p> 194 <p>In brief, the code in <code>FingerFactory</code> above creates a 195 Deferred, to which we start to attach <em>callbacks</em>. The 196 deferred action in <code>FingerFactory</code> is actually a 197 fast-running expression consisting of one dictionary 198 method, <code>get</code>. Since this action can execute without 199 delay, <code>FingerFactory.getUser</code> 200 uses <code>defer.succeed</code> to create a Deferred which already has 201 a result, meaning its return value will be passed immediately to the 202 first callback function, which turns out to 203 be <code>FingerProtocol.writeResponse</code>. We've also defined 204 an <em>errback</em> (appropriately 205 named <code>FingerProtocol.onError</code>) that will be called instead 206 of <code>writeResponse</code> if something goes wrong.</p> 203 207 204 208 <h2>Run 'finger' Locally</h2> 205 209 206 210 <a href="listings/finger/finger09.py" class="py-listing">finger09.py</a> 207 211 208 <p>This example also makes use of a <code>Deferred</code>. 209 <code>twisted.internet.utils.getProcessOutput</code> is a non-blocking version 210 of Python's <code>commands.getoutput</code>: it runs a shell command 211 (<code>finger</code>, in this case) and captures its standard output. However, 212 <code>getProcessOutput</code> returns a <code>Deferred</code> instead of the 213 output itself. Since <code>FingerProtocol.lineReceived</code> is already 214 expecting a Deferred to be returned by <code>getUser</code>, it doesn't need to 215 be changed, and it returns the standard output as the finger result.</p> 212 <p>This example also makes use of a 213 Deferred. <code>twisted.internet.utils.getProcessOutput</code> is a 214 non-blocking version of Python's <code>commands.getoutput</code>: it 215 runs a shell command (<code>finger</code>, in this case) and captures 216 its standard output. However, <code>getProcessOutput</code> returns a 217 Deferred instead of the output itself. 218 Since <code>FingerProtocol.lineReceived</code> is already expecting a 219 Deferred to be returned by <code>getUser</code>, it doesn't need to be 220 changed, and it returns the standard output as the finger result.</p> 216 221 217 222 <p>Note that in this case the shell's built-in <code>finger</code> command is 218 223 simply run with whatever arguments it is given. This is probably insecure, so … … 222 227 223 228 <h2>Read Status from the Web</h2> 224 229 225 <p>The web. That invention which has infiltrated homes around the world finally 226 gets through to our invention. In this case we use the built-in Twisted web 227 client via <code>twisted.web.client.getPage</code>, a non-blocking version of 228 Python's <code>urllib2.urlopen(URL).read()</code>. Like 229 <code>getProcessOutput</code> it returns a <code>Deferred</code> which will be 230 called back with a string, and can thus be used as a drop-in replacement.</p> 230 <p>The web. That invention which has infiltrated homes around the 231 world finally gets through to our invention. In this case we use the 232 built-in Twisted web client 233 via <code>twisted.web.client.getPage</code>, a non-blocking version of 234 Python's <code>urllib2.urlopen(URL).read()</code>. 235 Like <code>getProcessOutput</code> it returns a Deferred which will be 236 called back with a string, and can thus be used as a drop-in 237 replacement.</p> 231 238 232 239 <p>Thus, we have examples of three different database back-ends, none of which 233 240 change the protocol class. In fact, we will not have to change the protocol … … 279 286 280 287 <a href="listings/finger/finger11.tac" class="py-listing">finger11.tac</a> 281 288 282 <p>Instead of using <code>reactor.listenTCP</code> as in the above examples, 283 here we are using its application-aware counterpart, 284 <code>internet.TCPServer</code>. Notice that when it is instantiated, the 285 application object itself does not reference either the protocol or the factory. 286 Any services (such as <code>TCPServer</code>) which have the application as 287 their parent will be started when the application is started by twistd. The 288 application object is more useful for returning an object that supports the 289 <code class="API" 289 290 <p>Instead of using <code>reactor.listenTCP</code> as in the above 291 examples, here we are using its application-aware 292 counterpart, <code>internet.TCPServer</code>. Notice that when it is 293 instantiated, the application object itself does not reference either 294 the protocol or the factory. Any services (such as TCPServer) which 295 have the application as their parent will be started when the 296 application is started by twistd. The application object is more 297 useful for returning an object that supports the <code class="API" 290 298 base="twisted.application.service">IService</code>, <code class="API" 291 299 base="twisted.application.service">IServiceCollection</code>, <code class="API" 292 base="twisted.application.service">IProcess</code>, and <code class="API"293 base="twisted.persisted">sob.IPersistable</code> interfaces with the given 294 parameters; we'll be seeing these in the next part of the tutorial. Asthe295 parent of the <code>TCPServer</code> we opened, the application lets us manage 296 the <code>TCPServer</code>.</p>300 base="twisted.application.service">IProcess</code>, 301 and <code class="API" base="twisted.persisted">sob.IPersistable</code> 302 interfaces with the given parameters; we'll be seeing these in the 303 next part of the tutorial. As the parent of the TCPServer we opened, 304 the application lets us manage the TCPServer.</p> 297 305 298 306 <p>With the daemon running on the standard finger port, you can test it with 299 307 the standard finger command: <code>finger moshez</code>.</p> -
doc/core/howto/tutorial/protocol.xhtml
Common subdirectories: doc/core/howto/tutorial/listings and doc/core/howto/tutorial/listings diff -bu doc/core/howto/tutorial/protocol.xhtml doc/core/howto/tutorial/protocol.xhtml
40 40 41 41 <a href="listings/finger/finger12.tac" class="py-listing">finger12.tac</a> 42 42 43 <p>This program has two protocol-factory-TCPServer pairs, which are both child 44 services of the application. Specifically, the 45 <code base="API" class="twisted.application.service.Service">setServiceParent</code> 46 method is used to define the two TCPServer services as children of 47 <code>application</code>, which implements 48 <code base="API" class="twisted.application.servce">IServiceCollection</code>. 49 Both services are thus started with the application.</p> 43 <p>This program has two protocol-factory-TCPServer pairs, which are 44 both child services of the application. Specifically, 45 the <code base="API" 46 class="twisted.application.service.Service">setServiceParent</code> 47 method is used to define the two TCPServer services as children 48 of <code>application</code>, which implements <code base="API" 49 class="twisted.application.servce">IServiceCollection</code>. Both 50 services are thus started with the application.</p> 51 50 52 51 53 <h2>Use Services to Make Dependencies Sane</h2> 52 54 … … 58 60 class with methods that will create factories on the fly. The service 59 61 also contains methods the factories will depend on.</p> 60 62 61 <p>The factory-creation methods, <code>getFingerFactory</code> and62 <code>getFingerSetterFactory</code>, follow this pattern:</p>63 <p>The factory-creation methods, <code>getFingerFactory</code> 64 and <code>getFingerSetterFactory</code>, follow this pattern:</p> 63 65 64 66 <ol> 65 67 66 <li>Instantiate a generic server factory,67 <code>twisted.internet.protocol.ServerFactory</code>.</li>68 <li>Instantiate a generic server 69 factory, <code>twisted.internet.protocol.ServerFactory</code>.</li> 68 70 69 71 <li>Set the protocol class, just like our factory class would have.</li> 70 72 71 73 <li>Copy a service method to the factory as a function attribute. The 72 function won't have access to the factory's <code>self</code>, but that's OK 73 because as a bound method it has access to the service's <code>self</code>, 74 which is what it needs. For <code>getUser</code>, a custom method defined in 75 the service gets copied. For <code>setUser</code>, a standard method of the 76 <code>users</code> dictionary is copied.</li> 74 function won't have access to the factory's <code>self</code>, but 75 that's OK because as a bound method it has access to the 76 service's <code>self</code>, which is what it needs. 77 For <code>getUser</code>, a custom method defined in the service gets 78 copied. For <code>setUser</code>, a standard method of 79 the <code>users</code> dictionary is copied.</li> 80 77 81 78 82 </ol> 79 83 … … 82 86 none of our protocol classes had to be changed, and neither will have to 83 87 change until the end of the tutorial.</p> 84 88 85 <p>As an application 86 <code class="API" base="twisted.application.service">Service</code> , this new 87 finger service implements the 88 <code class="API" base="twisted.application.service">IService</code> interface 89 and canbe started and stopped in a standardized manner. We'll make use of89 <p>As an application <code class="API" 90 base="twisted.application.service">service</code> , this new finger 91 service implements the <code class="API" 92 base="twisted.application.service">IService</code> interface and can 93 be started and stopped in a standardized manner. We'll make use of 90 94 this in the next example.</p> 91 95 92 96 <a href="listings/finger/finger13.tac" class="py-listing">finger13.tac</a> … … 104 108 105 109 <a href="listings/finger/finger14.tac" class="py-listing">finger14.tac</a> 106 110 107 <p>Since this version is reading data from a file (and refreshing the data every 108 30 seconds), there is no <code>FingerSetterFactory</code> and thus nothing 109 listening on port 1079.</p> 110 111 <p>Here we override the standard 112 <code class="API" base="twisted.application.service.Service">startService</code> 113 and 114 <code class="API" base="twisted.application.service.Service">stopService</code> 115 hooks in the Finger service, which is set up as a child service of 116 the application in the last line of the code. <code>startService</code> calls 117 <code>_read</code>, the function responsible for reading the data; 118 <code>reactor.callLater</code> is then used to schedule it to run again after 119 thirty seconds every time it is called. <code>reactor.callLater</code> returns 120 an object that lets us cancel the scheduled run in <code>stopService</code> 121 using its <code>cancel</code> method.</p> 111 <p>Since this verison is reading data from a file (and refreshing the data 112 every 30 seconds), there is no <code>FingerSetterFactory</code> and thus 113 nothing listening on port 1079.</p> 114 115 <p>Here we override the standard <code class="API" 116 base="twisted.application.service.Service">startService</code> 117 and <code class="API" 118 base="twisted.application.service.Service">stopService</code> hooks in 119 the Finger service, which is set up as a child service of the 120 application in the last line of the code. <code>startService</code> 121 calls <code>_read</code>, the function responsible for reading the 122 data; <code>reactor.callLater</code> is then used to schedule it to 123 run again after thirty seconds every time it is 124 called. <code>reactor.callLater</code> returns an object that lets us 125 cancel the scheduled run in <code>stopService</code> using 126 its <code>cancel</code> method.</p> 122 127 123 128 <h2>Announce on Web, Too</h2> 124 129 125 <p>The same kind of service can also produce things useful for 126 other protocols. For example, in twisted.web, the factory 127 itself(<code base="API" class="twisted.web.server">Site</code>) is almost128 never subclassed — instead, it is given a resource, which represents the tree129 of resources available via URLs. That hierarchy is navigated by 130 <code base="API" class="twisted.web.server">Site</code> and overriding it 131 dynamically is possible with 132 <code base="API"class="twisted.web.resource.Resource">getChild</code>.</p>130 <p>The same kind of service can also produce things useful for other 131 protocols. For example, in twisted.web, the factory itself 132 (<code base="API" class="twisted.web.server">Site</code>) is almost 133 never subclassed — instead, it is given a resource, which 134 represents the tree of resources available via URLs. That hierarchy is 135 navigated by <code base="API" class="twisted.web.server">Site</code> 136 and overriding it dynamically is possible with <code base="API" 137 class="twisted.web.resource.Resource">getChild</code>.</p> 133 138 134 139 <p>To integrate this into the Finger application (just because we can), we set 135 140 up a new TCPServer that calls the <code base="API" … … 153 158 154 159 <a href="listings/finger/finger16.tac" class="py-listing">finger16.tac</a> 155 160 156 <p><code>FingerService</code> now has another new function, 157 <code>getIRCbot</code>, which returns the 158 <code>ReconnectingClientFactory</code>. This factory in turn will instantiate 159 the <code>IRCReplyBot</code> protocol. The IRCBot is configured in the last 160 line to connect to <code>irc.freenode.org</code> with a nickname of 161 <code>fingerbot</code>.</p> 162 163 <p>By overriding <code>irc.IRCClient.connectionMade</code>, 164 <code>IRCReplyBot</code> can access the <code>nickname</code> attribute of the 165 factory that instantiated it.</p> 161 <p><code>FingerService</code> now has another new 162 function, <code>getIRCbot</code>, which returns 163 the <code>ReconnectingClientFactory</code>. This factory in turn will 164 instantiate the <code>IRCReplyBot</code> protocol. The IRCBot is 165 configured in the last line to connect 166 to <code>irc.freenode.org</code> with a nickname 167 of <code>fingerbot</code>.</p> 168 169 <p>By 170 overriding <code>irc.IRCClient.connectionMade</code>, <code>IRCReplyBot</code> 171 can access the <code>nickname</code> attribute of the factory that 172 instantiated it.</p> 166 173 167 174 <h2>Add XML-RPC Support</h2> 168 175 -
doc/core/howto/tutorial/web.xhtml
Only in doc/core/howto/tutorial: .svn diff -bu doc/core/howto/tutorial/web.xhtml doc/core/howto/tutorial/web.xhtml
13 13 <p> This is the sixth part of the Twisted tutorial <a 14 14 href="index.xhtml">Twisted from Scratch, or The Evolution of Finger</a>.</p> 15 15 16 <p>In this part, we demonstrate adding a web frontend using simple <code 17 class="API">twisted.web.resource.Resource</code> objects: <code 18 class="python">UserStatusTree</code>, which will produce a listing of all 19 users at the base URL (<code>/</code>) of our site; <code 20 class="python">UserStatus</code>, which gives the status of each user at the 21 location <code>/username</code>; and <code class="python">UserStatusXR</code>, 22 which exposes an XMLRPC interface to <code class="python">getUser</code> and 23 <code class="python">getUsers</code> functions at the URL <code>/RPC2</code>.</p> 16 <p>In this part, we demonstrate adding a web frontend using 17 simple <code class="API">twisted.web.resource.Resource</code> 18 objects: <code class="python">UserStatusTree</code>, which will 19 produce a listing of all users at the base URL (<code>/</code>) of our 20 site; <code class="python">UserStatus</code>, which gives the status 21 of each user at the locaton <code>/username</code>; 22 and <code class="python">UserStatusXR</code>, which exposes an XMLRPC 23 interface to <code class="python">getUser</code> 24 and <code class="python">getUsers</code> functions at the 25 URL <code>/RPC2</code>.</p> 24 26 25 27 <p>In this example we construct HTML segments manually. If the web interface 26 28 was less trivial, we would want to use more sophisticated web templating and
