Ticket #4568: high-level.xhtml.patch

File high-level.xhtml.patch, 22.9 KB (added by jdb, 4 years ago)

Adapted the lore input of the articles in the "High-Level Twisted" section of the core howto

  • doc/core/howto/application.xhtml

    diff --git a/doc/core/howto/application.xhtml b/doc/core/howto/application.xhtml
    index 79f19db..3b6601a 100644
    a b Client service. </p> 
    9595 
    9696<h3>twistd and tac</h3><a name="twistd" /> 
    9797 
    98 <p>To handle start-up and configuration of your Twisted application, the 
    99 Twisted Application infrastructure uses <code>.tac</code> files. 
    100 <code>.tac</code> are Python files which configure an <code class="API" 
    101 base="twisted.application.service">Application</code> object and assign this 
    102 object to the top-level variable <q><code>application</code></q>.</p> 
     98<p>To handle start-up and configuration of your Twisted application, 
     99the Twisted Application infrastructure uses <code>.tac</code> 
     100files. <code>.tac</code> are Python files which configure 
     101an <code class="API" 
     102base="twisted.application.service">Application</code> object and 
     103assign this object to the top-level 
     104variable <q><code>application</code></q>.</p> 
    103105 
    104106<p>The following is a simple example of a <code>.tac</code> file:</p> 
    105107 
    106108<a href="listings/application/service.tac" class="py-listing">service.tac</a> 
    107109 
    108 <p><code>twistd</code> is a program that runs Twisted applications using a 
    109 <code>.tac</code> file. In its most simple form, it takes a single argument 
    110 <code>-y</code> and a tac file name. For example, you can run the above server 
    111 with the command <code class="shell">twistd -y service.tac</code>.</p> 
     110<p><code>twistd</code> is a program that runs Twisted applications 
     111using a <code>.tac</code> file. In its most simple form, it takes a 
     112single argument <code>-y</code> and a tac file name. For example, you 
     113can run the above server with the command <code class="shell">twistd 
     114-y service.tac</code>.</p> 
    112115 
    113 <p>By default, <code>twistd</code> daemonizes and logs to a file called 
    114 <code>twistd.log</code>. More usually, when debugging, you will want your 
    115 application to run in the foreground and log to the command line. To run the 
    116 above file like this, use the command <code class="shell">twistd -noy 
    117 service.tac</code></p> 
     116<p>By default, <code>twistd</code> daemonizes and logs to a file 
     117called <code>twistd.log</code>. More usually, when debugging, you will 
     118want your application to run in the foreground and log to the command 
     119line. To run the above file like this, use the 
     120command <code class="shell">twistd -noy service.tac</code></p> 
    118121 
    119122<p>For more information, see the <code>twistd</code> man page.</p> 
    120123 
    121124<h3>Customizing <code>twistd</code> logging in a .tac application</h3> 
    122125 
    123126<p> 
    124 The logging behavior can be customized through an API 
    125 accessible from <code>.tac</code> files.  The <code class="API" 
    126 base="twisted.python.log">ILogObserver</code> component can be 
    127 set on an Application in order to customize the default log observer that 
    128 <code>twistd</code> will use. 
     127The logging behavior can be customized through an API accessible 
     128from <code>.tac</code> files.  The <code class="API" 
     129base="twisted.python.log">ILogObserver</code> component can be set on 
     130an Application in order to customize the default log observer 
     131that <code>twistd</code> will use. 
    129132</p> 
    130133 
    131134<p> 
    application.setComponent(ILogObserver, FileLogObserver(logfile).emit) 
    146149 
    147150<p> 
    148151invoking <code class="shell">twistd -y my.tac</code> will create a log file 
    149 at<code>/tmp/my.log</code>. 
     152at <code>/tmp/my.log</code>. 
    150153</p> 
    151154 
    152155<h3>Services provided by Twisted</h3> 
    corresponds to reactor.connectTCP. </p> 
    253256<h3>Service Collection</h3> 
    254257 
    255258<p><code class="API" 
    256 base="twisted.application.service">IServiceCollection</code> objects contain 
    257 <code class="API" base="twisted.application.service">IService</code> objects. 
    258 IService objects can be added to IServiceCollection by calling <code class="API" 
    259 base="twisted.application.service.IService">setServiceParent</code> and detached 
    260 by using <code class="API" 
     259base="twisted.application.service">IServiceCollection</code> objects 
     260contain <code class="API" 
     261base="twisted.application.service">IService</code> objects.  IService 
     262objects can be added to IServiceCollection by 
     263calling <code class="API" 
     264base="twisted.application.service.IService">setServiceParent</code> 
     265and detached by using <code class="API" 
    261266base="twisted.application.service.IService">disownServiceParent</code>.</p> 
    262267 
    263268<p>The standard implementation of IServiceCollection is <code class="API" 
  • doc/core/howto/basics.xhtml

    diff --git a/doc/core/howto/basics.xhtml b/doc/core/howto/basics.xhtml
    index df27fba..20b00ed 100644
    a b  
    1212 
    1313<h2>Application</h2> 
    1414 
    15 <p>Twisted programs usually work with 
    16 <code class="API">twisted.application.service.Application</code>. 
    17 This class usually holds all persistent configuration of 
    18 a running server -- ports to bind to, places where connections 
    19 to must be kept or attempted, periodic actions to do and almost 
    20 everything else. It is the root object in a tree of services implementing 
    21 <code class="API" base="twisted.application.service">IService</code>.</p> 
     15<p>Twisted programs usually work 
     16with <code class="API">twisted.application.service.Application</code>. 
     17This class usually holds all persistent configuration of a running 
     18server -- ports to bind to, places where connections to must be kept 
     19or attempted, periodic actions to do and almost everything else. It is 
     20the root object in a tree of services implementing <code class="API" 
     21base="twisted.application.service">IService</code>.</p> 
    2222 
    2323<p>Other HOWTOs describe how to write custom code for Applications, 
    2424but this one describes how to use already written code (which can be 
    directory. When a straight Python file which defines an <code>Application</code> 
    5252object called <code>application</code> is used, use the <code class="shell">-y</code> 
    5353option.</p> 
    5454 
    55 <p>When <code class="shell">twistd</code> runs, it records its process id in a 
    56 <code>twistd.pid</code> file (this can be configured via a command line 
    57 switch). In order to shutdown the <code class="shell">twistd</code> process, kill that 
    58 pid (usually you would do <code class="shell">kill `cat twistd.pid`</code>). 
     55<p>When <code class="shell">twistd</code> runs, it records its process 
     56id in a <code>twistd.pid</code> file (this can be configured via a 
     57command line switch). In order to shutdown 
     58the <code class="shell">twistd</code> process, kill that pid (usually 
     59you would do <code class="shell">kill `cat twistd.pid`</code>). 
    5960</p> 
    6061 
    6162<p>As always, the gory details are in the manual page.</p> 
    pid (usually you would do <code class="shell">kill `cat twistd.pid`</code>). 
    6364<h2>OS Integration</h2> 
    6465 
    6566<p> 
    66 If you have an Application that runs with <code class="shell">twistd</code>, 
    67 you can easily deploy it on RedHat Linux or Debian GNU/Linux based systems 
    68 using the <code class="shell">tap2deb</code> or <code 
    69 class="shell">tap2rpm</code> tools. These take a Twisted Application file (of 
    70 any of the supported formats — Python source, XML or pickle), and build a 
    71 Debian or RPM package (respectively) that installs the Application as a system 
    72 service. The package includes the Application file, a default 
    73 <code>/etc/init.d/</code> script that starts and stops the process with twistd, 
    74 and post-installation scripts that configure the Application to be run in the 
    75 appropriate init levels. 
     67If you have an Application that runs 
     68with <code class="shell">twistd</code>, you can easily deploy it on 
     69RedHat Linux or Debian GNU/Linux based systems using 
     70the <code class="shell">tap2deb</code> 
     71or <code class="shell">tap2rpm</code> tools. These take a Twisted 
     72Application file (of any of the supported formats — Python source, XML 
     73or pickle), and build a Debian or RPM package (respectively) that 
     74installs the Application as a system service. The package includes the 
     75Application file, a default <code>/etc/init.d/</code> script that 
     76starts and stops the process with twistd, and post-installation 
     77scripts that configure the Application to be run in the appropriate 
     78init levels. 
    7679</p> 
    7780 
    7881<!-- Is "note" really the right class to be using here? --> 
    79 <div class="note"> 
    80 <code class="shell">tap2rpm</code> and <code class="shell">tap2deb</code> do 
    81 not package your entire application and dependent code, just the Twisted 
    82 Application file. You will need to find some other way to package your Python 
    83 code, such as <code class="API">distutils</code>' <code>bdist_rpm</code> 
    84 command. 
     82<div class="note"> <code class="shell">tap2rpm</code> 
     83and <code class="shell">tap2deb</code> do not package your entire 
     84application and dependent code, just the Twisted Application file. You 
     85will need to find some other way to package your Python code, such 
     86as <code class="API">distutils</code>' <code>bdist_rpm</code> command. 
    8587</div> 
    8688 
    8789<p> 
  • doc/core/howto/components.xhtml

    diff --git a/doc/core/howto/components.xhtml b/doc/core/howto/components.xhtml
    index 3567d6e..135e4ef 100644
    a b  
    88<body> 
    99<h1>Components: Interfaces and Adapters</h1> 
    1010 
    11 <p>Object oriented programming languages allow programmers to reuse portions of 
    12 existing code by creating new <q>classes</q> of objects which subclass another 
    13 class.  When a class subclasses another, it is said to <em>inherit</em> all of its 
    14 behaviour.  The subclass can then <q>override</q> and <q>extend</q> the behavior 
    15 provided to it by the superclass. Inheritance is very useful in many situations, 
    16 but because it is so convenient to use, often becomes abused in large software 
    17 systems, especially when multiple inheritance is involved. One solution is to 
    18 use <em>delegation</em> instead of <q>inheritance</q> where appropriate. 
    19 Delegation is simply the act of asking <em>another</em> object to perform a task 
    20 for an object. To support this design pattern, which is often referred to as the 
    21 <em>components</em> pattern because it involves many small interacting components, 
    22 <em>interfaces</em> and <em>adapters</em> were created by the Zope 3 team.</p> 
     11<p>Object oriented programming languages allow programmers to reuse 
     12portions of existing code by creating new <q>classes</q> of objects 
     13which subclass another class.  When a class subclasses another, it is 
     14said to <em>inherit</em> all of its behaviour.  The subclass can 
     15then <q>override</q> and <q>extend</q> the behavior provided to it by 
     16the superclass. Inheritance is very useful in many situations, but 
     17because it is so convenient to use, often becomes abused in large 
     18software systems, especially when multiple inheritance is 
     19involved. One solution is to use <em>delegation</em> instead 
     20of <q>inheritance</q> where appropriate.  Delegation is simply the act 
     21of asking <em>another</em> object to perform a task for an object. To 
     22support this design pattern, which is often referred to as 
     23the <em>components</em> pattern because it involves many small 
     24interacting components, <em>interfaces</em> and <em>adapters</em> were 
     25created by the Zope 3 team.</p> 
    2326 
    2427<p><q>Interfaces</q> are simply markers which objects can use to say <q>I 
    2528implement this interface</q>. Other objects may then make requests like 
    technique called <em>composition</em>, which relies on delegation rather than 
    100103inheritance to break code into small reusable chunks. Let us continue with the 
    101104Multiple Inheritance example, though, because it is often used in practice.</p> 
    102105 
    103 <p>What if both the Color and the Area base class defined the same method, 
    104 perhaps <code>calculate</code>? Where would the implementation come from? The 
    105 implementation that is located for <code>Square().calculate()</code> depends on 
    106 the method resolution order, or MRO, and can change when programmers change 
    107 seemingly unrelated things by refactoring classes in other parts of the system, 
    108 causing obscure bugs. Our first thought might be to change the calculate method 
    109 name to avoid name clashes, to perhaps <code>calculateArea</code> and 
    110 <code>calculateColor</code>.  While explicit, this change could potentially 
    111 require a large number of changes throughout a system, and is error-prone, 
    112 especially when attempting to integrate two systems which you didn't write.</p> 
     106<p>What if both the Color and the Area base class defined the same 
     107method, perhaps <code>calculate</code>? Where would the implementation 
     108come from? The implementation that is located 
     109for <code>Square().calculate()</code> depends on the method resolution 
     110order, or MRO, and can change when programmers change seemingly 
     111unrelated things by refactoring classes in other parts of the system, 
     112causing obscure bugs. Our first thought might be to change the 
     113calculate method name to avoid name clashes, to 
     114perhaps <code>calculateArea</code> and <code>calculateColor</code>. 
     115While explicit, this change could potentially require a large number 
     116of changes throughout a system, and is error-prone, especially when 
     117attempting to integrate two systems which you didn't write.</p> 
    113118 
    114119<p>Let's imagine another example. We have an electric appliance, say a hair 
    115120dryer. The hair dryer is american voltage. We have two electric sockets, one of 
    I was plugged in improperly and 
    151156now you have no hair dryer any more. 
    152157</pre> 
    153158 
    154 <p>We are going to attempt to solve this problem by writing an Adapter for the 
    155 <code>ForeignSocket</code> which converts the voltage for use with an American 
    156 hair dryer. An Adapter is a class which is constructed with one and only one 
    157 argument, the <q>adaptee</q> or <q>original</q> object. In this example, we 
    158 will show all code involved for clarity:</p> 
     159<p>We are going to attempt to solve this problem by writing an Adapter 
     160for the <code>ForeignSocket</code> which converts the voltage for use 
     161with an American hair dryer. An Adapter is a class which is 
     162constructed with one and only one argument, the <q>adaptee</q> 
     163or <q>original</q> object. In this example, we will show all code 
     164involved for clarity:</p> 
    159165 
    160166<pre class="python"> 
    161167class AdaptToAmericanSocket: 
    the class block do not have any method body! Since Python does not have any 
    213219native language-level support for Interfaces like Java does, this is what 
    214220distinguishes an Interface definition from a Class.</p> 
    215221 
    216 <p>Now that we have a defined Interface, we can talk about objects using terms 
    217 like this: <q>The <code>AmericanSocket</code> class implements the 
    218 <code>IAmericanSocket</code> interface</q> and <q>Please give me an object which 
     222<p>Now that we have a defined Interface, we can talk about objects 
     223using terms like this: <q>The <code>AmericanSocket</code> class 
     224implements the <code>IAmericanSocket</code> interface</q> 
     225and <q>Please give me an object which 
    219226adapts <code>ForeignSocket</code> to the <code>IAmericanSocket</code> 
    220 interface</q>. We can make <em>declarations</em> about what interfaces a certain 
    221 class implements, and we can request adapters which implement a certain 
    222 interface for a specific class.</p> 
     227interface</q>. We can make <em>declarations</em> about what interfaces 
     228a certain class implements, and we can request adapters which 
     229implement a certain interface for a specific class.</p> 
    223230 
    224231<p>Let's look at how we declare that a class implements an interface:</p> 
    225232 
    class AmericanSocket: 
    234241        return 110 
    235242</pre> 
    236243 
    237 <p>So, to declare that a class implements an interface, we simply call 
    238 <code>zope.interface.implements</code> at the class level.</p> 
     244<p>So, to declare that a class implements an interface, we simply 
     245call <code>zope.interface.implements</code> at the class level.</p> 
    239246 
    240 <p>Now, let's say we want to rewrite the <code>AdaptToAmericanSocket</code> 
    241 class as a real adapter. In this case we also specify it as implementing 
    242 <code>IAmericanSocket</code>:</p> 
     247<p>Now, let's say we want to rewrite 
     248the <code>AdaptToAmericanSocket</code> class as a real adapter. In 
     249this case we also specify it as 
     250implementing <code>IAmericanSocket</code>:</p> 
    243251 
    244252<pre class="python"> 
    245253from zope.interface import implements 
    class AdaptToAmericanSocket: 
    258266        return self.original.voltage() / 2 
    259267</pre> 
    260268 
    261 <p>Notice how we placed the implements declaration on this adapter class. So 
    262 far, we have not achieved anything by using components other than requiring us 
    263 to type more. In order for components to be useful, we must use the 
    264 <em>component registry</em>. Since <code>AdaptToAmericanSocket</code> implements 
    265 <code>IAmericanSocket</code> and regulates the voltage of a 
    266 <code>ForeignSocket</code> object, we can <em>register 
    267 <code>AdaptToAmericanSocket</code> as an <code>IAmericanSocket</code> adapter 
    268 for the <code>ForeignSocket</code> class</em>. It is easier to see how this is 
    269 done in code than to describe it:</p> 
     269<p>Notice how we placed the implements declaration on this adapter 
     270class. So far, we have not achieved anything by using components other 
     271than requiring us to type more. In order for components to be useful, 
     272we must use the <em>component 
     273registry</em>. Since <code>AdaptToAmericanSocket</code> 
     274implements <code>IAmericanSocket</code> and regulates the voltage of 
     275a <code>ForeignSocket</code> object, we 
     276can <em>register </em> <code>AdaptToAmericanSocket</code> <em> as 
     277an </em> <code>IAmericanSocket</code> <em> adapter for 
     278the </em> <code>ForeignSocket</code> <em>class</em>. It is easier to see how 
     279this is done in code than to describe it:</p> 
    270280 
    271281<pre class="python"> 
    272282from zope.interface import Interface, implements 
    False 
    321331</pre> 
    322332 
    323333<p>As you can see, the <code>AmericanSocket</code> instance claims to 
    324 implement <code>IAmericanSocket</code>, but the <code>ForeignSocket</code> 
    325 does not. If we wanted to use the <code>HairDryer</code> with the 
    326 <code>AmericanSocket</code>, we could know that it would be safe to do so by 
    327 checking whether it implements <code>IAmericanSocket</code>. However, if we 
    328 decide we want to use <code>HairDryer</code> with a <code>ForeignSocket</code> 
    329 instance, we must <em>adapt</em> it to <code>IAmericanSocket</code> before 
    330 doing so.  We use the interface object to do this:</p> 
     334implement <code>IAmericanSocket</code>, but 
     335the <code>ForeignSocket</code> does not. If we wanted to use 
     336the <code>HairDryer</code> with the <code>AmericanSocket</code>, we 
     337could know that it would be safe to do so by checking whether it 
     338implements <code>IAmericanSocket</code>. However, if we decide we want 
     339to use <code>HairDryer</code> with a <code>ForeignSocket</code> 
     340instance, we must <em>adapt</em> it to <code>IAmericanSocket</code> 
     341before doing so.  We use the interface object to do this:</p> 
    331342 
    332343<pre class="python-interpreter"> 
    333344&gt;&gt;&gt; IAmericanSocket(fs) 
    334345&lt;__main__.AdaptToAmericanSocket instance at 0x1a5120&gt; 
    335346</pre> 
    336347 
    337 <p>When calling an interface with an object as an argument, the interface 
    338 looks in the adapter registry for an adapter which implements the interface for 
    339 the given instance's class. If it finds one, it constructs an instance of the 
    340 Adapter class, passing the constructor the original instance, and returns it. 
    341 Now the <code>HairDryer</code> can safely be used with the adapted 
    342 <code>ForeignSocket</code>. But what happens if we attempt to adapt an object 
    343 which already implements <code>IAmericanSocket</code>? We simply get back the 
    344 original instance:</p> 
     348<p>When calling an interface with an object as an argument, the 
     349interface looks in the adapter registry for an adapter which 
     350implements the interface for the given instance's class. If it finds 
     351one, it constructs an instance of the Adapter class, passing the 
     352constructor the original instance, and returns it.  Now 
     353the <code>HairDryer</code> can safely be used with the 
     354adapted <code>ForeignSocket</code>. But what happens if we attempt to 
     355adapt an object which already implements <code>IAmericanSocket</code>? 
     356We simply get back the original instance:</p> 
    345357 
    346358<pre class="python-interpreter"> 
    347359&gt;&gt;&gt; IAmericanSocket(am) 
    class Root(Referenceable): 
    395407    implements(IPBRoot) 
    396408</pre> 
    397409 
    398 <p>Suppose you have your own class which implements your 
    399 <code>IMyInterface</code> interface:</p> 
     410<p>Suppose you have your own class which implements 
     411your <code>IMyInterface</code> interface:</p> 
    400412 
    401413<pre class="python"> 
    402414from zope.interface import implements, Interface 
    class MyThing: 
    408420    implements(IMyInterface) 
    409421</pre> 
    410422 
    411 <p>Now if you want to make this class inherit from <code>pb.Root</code>,  
    412 the interfaces code will automatically determine that it also implements 
    413 <code>IPBRoot</code>:</p> 
     423<p>Now if you want to make this class inherit 
     424from <code>pb.Root</code>, the interfaces code will automatically 
     425determine that it also implements <code>IPBRoot</code>:</p> 
    414426 
    415427<pre class="python"> 
    416428from twisted.spread import pb 
    class MyThing(pb.Root): 
    429441True 
    430442</pre> 
    431443 
    432 <p>If you want <code>MyThing</code> to inherit from <code>pb.Root</code> but 
    433 <em>not</em> implement <code>IPBRoot</code> like <code>pb.Root</code> does, 
     444<p>If you want <code>MyThing</code> to inherit 
     445from <code>pb.Root</code> but <em>not</em> 
     446implement <code>IPBRoot</code> like <code>pb.Root</code> does, 
    434447use <code>implementOnly</code>:</p> 
    435448 
    436449<pre class="python"> 
  • doc/core/howto/cred.xhtml

    diff --git a/doc/core/howto/cred.xhtml b/doc/core/howto/cred.xhtml
    index f16080b..dae222b 100644
    a b This has only 2 methods -</p> 
    6565<ul> 
    6666<li><code class="API" base="twisted.cred.portal.Portal">login</code><code>(credentials, mind, *interfaces)</code> 
    6767 
    68 <p>The docstring is quite expansive (see <code class="API">twisted.cred.portal</code>), but in 
    69 brief, this is what you call when you need to call in order to connect 
    70 a user to the system.  Typically you only pass in one interface, and the mind is 
    71 <code class="python">None</code>. The interfaces are the possible interfaces the returned 
    72 avatar is expected to implement, in order of preference. 
    73 The result is a deferred which fires a tuple of:</p> 
     68<p>The docstring is quite expansive 
     69(see <code class="API">twisted.cred.portal</code>), but in brief, this 
     70is what you call when you need to call in order to connect a user to 
     71the system.  Typically you only pass in one interface, and the mind 
     72is <code class="python">None</code>. The interfaces are the possible 
     73interfaces the returned avatar is expected to implement, in order of 
     74preference.  The result is a deferred which fires a tuple of:</p> 
    7475    <ul> 
    7576        <li>interface the avatar implements (which was one of the interfaces passed in the *interfaces 
    7677tuple)</li> 
    href="tap.xhtml">Writing a twistd plugin</a> document.</p> 
    343344 
    344345   <h3>Building a cred plugin</h3> 
    345346 
    346 <p> To build a plugin for cred, you should first define an <code 
    347 class="python">authType</code>, a short one-word string that defines 
    348 your plugin to the command-line. Once you have this, the convention is 
    349 to create a file named <code>myapp_plugins.py</code> in the 
    350 <code class="API">twisted.plugins</code> module path. </p> 
     347<p> To build a plugin for cred, you should first define 
     348an <code class="python">authType</code>, a short one-word string that 
     349defines your plugin to the command-line. Once you have this, the 
     350convention is to create a file named <code>myapp_plugins.py</code> in 
     351the <code class="API">twisted.plugins</code> module path. </p> 
    351352 
    352353<p> Below is an example file structure for an application that defines 
    353354such a plugin: </p>