Ticket #4569: tutorial2.xhtml.patch

File tutorial2.xhtml.patch, 18.1 KB (added by jdb, 6 years ago)
  • doc/core/howto/tutorial/intro.xhtml

    diff -bu doc/core/howto/tutorial/intro.xhtml doc/core/howto/tutorial/intro.xhtml
     
    2727No Plan.
    2828</pre>
    2929
    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
     31the <code>fingerd</code> <a href="../glossary.xhtml#Daemon">daemon</a>
     32running you'll get a "Connection Refused" error. Paranoid sysadmins
     33keep <code>fingerd</code> off or limit the output to hinder crackers
     34and harassers. The above format is the standard <code>fingerd</code>
     35default, but an alternate implementation can output anything it wants,
     36such as automated responsibility status for everyone in an
     37organization. You can also define pseudo "users", which are
     38essentially keywords.</p>
    3839
    3940<p>This portion of the tutorial makes use of factories and protocols as
    4041introduced in the <a href="../servers.xhtml">Writing a TCP Server howto</a> and
     
    7576over and over again, responding to network events and making scheduled calls to
    7677code.</p>
    7778
    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
     80from; <code>from twisted.internet import reactor</code> returns the
     81current reactor.  If you haven't chosen a reactor class yet, it
     82automatically chooses the default.  See
     83the <a href="../reactor-basics.xhtml">Reactor Basics HOWTO</a> for
     84more information.</p>
    8385
    8486<h2>Do Nothing</h2>
    8587
     
    189191other operations in the meantime, and waits for some signal that data is ready
    190192to be processed before returning to that process.</p>
    191193
    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
     195Deferred, to which we start to attach <em>callbacks</em>.  The
     196deferred action in <code>FingerFactory</code> is actually a
     197fast-running expression consisting of one dictionary
     198method, <code>get</code>. Since this action can execute without
     199delay, <code>FingerFactory.getUser</code>
     200uses <code>defer.succeed</code> to create a Deferred which already has
     201a result, meaning its return value will be passed immediately to the
     202first callback function, which turns out to
     203be <code>FingerProtocol.writeResponse</code>.  We've also defined
     204an <em>errback</em> (appropriately
     205named <code>FingerProtocol.onError</code>) that will be called instead
     206of <code>writeResponse</code> if something goes wrong.</p>
    203207
    204208<h2>Run 'finger' Locally</h2>
    205209
    206210<a href="listings/finger/finger09.py" class="py-listing">finger09.py</a>
    207211
    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
     213Deferred. <code>twisted.internet.utils.getProcessOutput</code> is a
     214non-blocking version of Python's <code>commands.getoutput</code>: it
     215runs a shell command (<code>finger</code>, in this case) and captures
     216its standard output.  However, <code>getProcessOutput</code> returns a
     217Deferred instead of the output itself.
     218Since <code>FingerProtocol.lineReceived</code> is already expecting a
     219Deferred to be returned by <code>getUser</code>, it doesn't need to be
     220changed, and it returns the standard output as the finger result.</p>
    216221
    217222<p>Note that in this case the shell's built-in <code>finger</code> command is
    218223simply run with whatever arguments it is given. This is probably insecure, so
     
    222227
    223228<h2>Read Status from the Web</h2>
    224229
    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
     231world finally gets through to our invention. In this case we use the
     232built-in Twisted web client
     233via <code>twisted.web.client.getPage</code>, a non-blocking version of
     234Python's <code>urllib2.urlopen(URL).read()</code>.
     235Like <code>getProcessOutput</code> it returns a Deferred which will be
     236called back with a string, and can thus be used as a drop-in
     237replacement.</p>
    231238
    232239<p>Thus, we have examples of three different database back-ends, none of which
    233240change the protocol class. In fact, we will not have to change the protocol
     
    279286
    280287<a href="listings/finger/finger11.tac" class="py-listing">finger11.tac</a>
    281288
    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
     291examples, here we are using its application-aware
     292counterpart, <code>internet.TCPServer</code>.  Notice that when it is
     293instantiated, the application object itself does not reference either
     294the protocol or the factory.  Any services (such as TCPServer) which
     295have the application as their parent will be started when the
     296application is started by twistd.  The application object is more
     297useful for returning an object that supports the <code class="API"
    290298base="twisted.application.service">IService</code>, <code class="API"
    291299base="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. As the
    295 parent of the <code>TCPServer</code> we opened, the application lets us manage
    296 the <code>TCPServer</code>.</p>
     300base="twisted.application.service">IProcess</code>,
     301and <code class="API" base="twisted.persisted">sob.IPersistable</code>
     302interfaces with the given parameters; we'll be seeing these in the
     303next part of the tutorial. As the parent of the TCPServer we opened,
     304the application lets us manage the TCPServer.</p>
    297305
    298306<p>With the daemon running on the standard finger port, you can test it with
    299307the 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
     
    4040
    4141<a href="listings/finger/finger12.tac" class="py-listing">finger12.tac</a>
    4242
    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
     44both child services of the application.  Specifically,
     45the <code base="API"
     46class="twisted.application.service.Service">setServiceParent</code>
     47method is used to define the two TCPServer services as children
     48of <code>application</code>, which implements <code base="API"
     49class="twisted.application.servce">IServiceCollection</code>.  Both
     50services are thus started with the application.</p>
     51
    5052
    5153<h2>Use Services to Make Dependencies Sane</h2>
    5254
     
    5860class with methods that will create factories on the fly. The service
    5961also contains methods the factories will depend on.</p>
    6062
    61 <p>The factory-creation methods, <code>getFingerFactory</code> and
    62 <code>getFingerSetterFactory</code>, follow this pattern:</p>
     63<p>The factory-creation methods, <code>getFingerFactory</code>
     64and <code>getFingerSetterFactory</code>, follow this pattern:</p>
    6365
    6466<ol>
    6567
    66 <li>Instantiate a generic server factory,
    67 <code>twisted.internet.protocol.ServerFactory</code>.</li>
     68<li>Instantiate a generic server
     69factory, <code>twisted.internet.protocol.ServerFactory</code>.</li>
    6870
    6971<li>Set the protocol class, just like our factory class would have.</li>
    7072
    7173<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>
     74function won't have access to the factory's <code>self</code>, but
     75that's OK because as a bound method it has access to the
     76service's <code>self</code>, which is what it needs.
     77For <code>getUser</code>, a custom method defined in the service gets
     78copied.  For <code>setUser</code>, a standard method of
     79the <code>users</code> dictionary is copied.</li>
     80
    7781
    7882</ol>
    7983
     
    8286none of our protocol classes had to be changed, and neither will have to
    8387change until the end of the tutorial.</p>
    8488
    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 can be started and stopped in a standardized manner.  We'll make use of
     89<p>As an application <code class="API"
     90base="twisted.application.service">service</code> , this new finger
     91service implements the <code class="API"
     92base="twisted.application.service">IService</code> interface and can
     93be started and stopped in a standardized manner.  We'll make use of
    9094this in the next example.</p>
    9195
    9296<a href="listings/finger/finger13.tac" class="py-listing">finger13.tac</a>
     
    104108
    105109<a href="listings/finger/finger14.tac" class="py-listing">finger14.tac</a>
    106110
    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
     112every 30 seconds), there is no <code>FingerSetterFactory</code> and thus
     113nothing listening on port 1079.</p>
     114
     115<p>Here we override the standard <code class="API"
     116base="twisted.application.service.Service">startService</code>
     117and <code class="API"
     118base="twisted.application.service.Service">stopService</code> hooks in
     119the Finger service, which is set up as a child service of the
     120application in the last line of the code. <code>startService</code>
     121calls <code>_read</code>, the function responsible for reading the
     122data; <code>reactor.callLater</code> is then used to schedule it to
     123run again after thirty seconds every time it is
     124called. <code>reactor.callLater</code> returns an object that lets us
     125cancel the scheduled run in <code>stopService</code> using
     126its <code>cancel</code> method.</p>
    122127
    123128<h2>Announce on Web, Too</h2>
    124129
    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 almost
    128 never subclassed &mdash; instead, it is given a resource, which represents the tree
    129 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
     131protocols. For example, in twisted.web, the factory itself
     132(<code base="API" class="twisted.web.server">Site</code>) is almost
     133never subclassed &mdash; instead, it is given a resource, which
     134represents the tree of resources available via URLs. That hierarchy is
     135navigated by <code base="API" class="twisted.web.server">Site</code>
     136and overriding it dynamically is possible with <code base="API"
     137class="twisted.web.resource.Resource">getChild</code>.</p>
    133138
    134139<p>To integrate this into the Finger application (just because we can), we set
    135140up a new TCPServer that calls the <code base="API"
     
    153158
    154159<a href="listings/finger/finger16.tac" class="py-listing">finger16.tac</a>
    155160
    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
     162function, <code>getIRCbot</code>, which returns
     163the <code>ReconnectingClientFactory</code>.  This factory in turn will
     164instantiate the <code>IRCReplyBot</code> protocol.  The IRCBot is
     165configured in the last line to connect
     166to <code>irc.freenode.org</code> with a nickname
     167of <code>fingerbot</code>.</p>
     168
     169<p>By
     170overriding <code>irc.IRCClient.connectionMade</code>, <code>IRCReplyBot</code>
     171can access the <code>nickname</code> attribute of the factory that
     172instantiated it.</p>
    166173
    167174<h2>Add XML-RPC Support</h2>
    168175
  • 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
     
    1313<p> This is the sixth part of the Twisted tutorial <a
    1414href="index.xhtml">Twisted from Scratch, or The Evolution of Finger</a>.</p>
    1515
    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
     17simple <code class="API">twisted.web.resource.Resource</code>
     18objects: <code class="python">UserStatusTree</code>, which will
     19produce a listing of all users at the base URL (<code>/</code>) of our
     20site; <code class="python">UserStatus</code>, which gives the status
     21of each user at the locaton <code>/username</code>;
     22and <code class="python">UserStatusXR</code>, which exposes an XMLRPC
     23interface to <code class="python">getUser</code>
     24and <code class="python">getUsers</code> functions at the
     25URL <code>/RPC2</code>.</p>
    2426
    2527<p>In this example we construct HTML segments manually. If the web interface
    2628was less trivial, we would want to use more sophisticated web templating and