Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > media > main-release > by-pkgid > db93d7191b12a3d5ce887da46fc79bf1 > files > 208

python-twisted-core-doc-2.5.0-3mdv2008.1.x86_64.rpm

<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: The Evolution of Finger: a Twisted finger client</title><link href="../../howto/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">The Evolution of Finger: a Twisted finger client</h1><div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Finger Proxy</a></li></ol></div><div class="content"><span></span><h2>Introduction<a name="auto0"></a></h2><p> This is the ninth part of the Twisted tutorial <a href="index.html">Twisted from Scratch, or The Evolution of Finger</a>.</p><p>In this part, we develop a client for the finger server: a proxy finger
server which forwards requests to another finger server.</p><h2>Finger Proxy<a name="auto1"></a></h2><p>Writing new clients with Twisted is much like writing new servers.
We implement the protocol, which just gathers up all the data, and
give it to the factory. The factory keeps a deferred which is triggered
if the connection either fails or succeeds. When we use the client,
we first make sure the deferred will never fail, by producing a message
in that case. Implementing a wrapper around client which just returns
the deferred is a common pattern.  While less flexible than
using the factory directly, it's also more convenient.</p><div class="py-listing"><pre>
<span class="py-src-comment"># finger proxy
</span><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-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">defer</span>, <span class="py-src-variable">protocol</span>, <span class="py-src-variable">reactor</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">protocols</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">basic</span>
<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">components</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Interface</span>, <span class="py-src-variable">implements</span>


<span class="py-src-keyword">def</span> <span class="py-src-identifier">catchError</span>(<span class="py-src-parameter">err</span>):
    <span class="py-src-keyword">return</span> <span class="py-src-string">&quot;Internal error in server&quot;</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerService</span>(<span class="py-src-parameter">Interface</span>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>():
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a list of strings&quot;&quot;&quot;</span>


<span class="py-src-keyword">class</span> <span class="py-src-identifier">IFingerFactory</span>(<span class="py-src-parameter">Interface</span>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">user</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a deferred returning a string&quot;&quot;&quot;</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">buildProtocol</span>(<span class="py-src-parameter">addr</span>):
        <span class="py-src-string">&quot;&quot;&quot;Return a protocol returning a string&quot;&quot;&quot;</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerProtocol</span>(<span class="py-src-parameter">basic</span>.<span class="py-src-parameter">LineReceiver</span>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">lineReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
        <span class="py-src-variable">d</span> = <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">catchError</span>)
        <span class="py-src-keyword">def</span> <span class="py-src-identifier">writeValue</span>(<span class="py-src-parameter">value</span>):
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">value</span>)
            <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">loseConnection</span>()
        <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">writeValue</span>)



<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerFactoryFromService</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ClientFactory</span>):

    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerFactory</span>)

    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerProtocol</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">service</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span> = <span class="py-src-variable">service</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">service</span>.<span class="py-src-variable">getUser</span>(<span class="py-src-variable">user</span>)


<span class="py-src-variable">components</span>.<span class="py-src-variable">registerAdapter</span>(<span class="py-src-variable">FingerFactoryFromService</span>,
                           <span class="py-src-variable">IFingerService</span>,
                           <span class="py-src-variable">IFingerFactory</span>)

<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerClient</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">Protocol</span>):

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span>(<span class="py-src-parameter">self</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">transport</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">user</span>+<span class="py-src-string">&quot;\r\n&quot;</span>)
        <span class="py-src-variable">self</span>.<span class="py-src-variable">buf</span> = []

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">dataReceived</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">buf</span>.<span class="py-src-variable">append</span>(<span class="py-src-variable">data</span>)

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionLost</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">reason</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">factory</span>.<span class="py-src-variable">gotData</span>(<span class="py-src-string">''</span>.<span class="py-src-variable">join</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">buf</span>))

<span class="py-src-keyword">class</span> <span class="py-src-identifier">FingerClientFactory</span>(<span class="py-src-parameter">protocol</span>.<span class="py-src-parameter">ClientFactory</span>):

    <span class="py-src-variable">protocol</span> = <span class="py-src-variable">FingerClient</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>
        <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>()

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">clientConnectionFailed</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">_</span>, <span class="py-src-parameter">reason</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">errback</span>(<span class="py-src-variable">reason</span>)

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">gotData</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">data</span>):
        <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">callback</span>(<span class="py-src-variable">data</span>)


<span class="py-src-keyword">def</span> <span class="py-src-identifier">finger</span>(<span class="py-src-parameter">user</span>, <span class="py-src-parameter">host</span>, <span class="py-src-parameter">port</span>=<span class="py-src-number">79</span>):
    <span class="py-src-variable">f</span> = <span class="py-src-variable">FingerClientFactory</span>(<span class="py-src-variable">user</span>)
    <span class="py-src-variable">reactor</span>.<span class="py-src-variable">connectTCP</span>(<span class="py-src-variable">host</span>, <span class="py-src-variable">port</span>, <span class="py-src-variable">f</span>)
    <span class="py-src-keyword">return</span> <span class="py-src-variable">f</span>.<span class="py-src-variable">d</span>


<span class="py-src-keyword">class</span> <span class="py-src-identifier">ProxyFingerService</span>(<span class="py-src-parameter">service</span>.<span class="py-src-parameter">Service</span>):
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IFingerService</span>)

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUser</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">user</span>):
        <span class="py-src-keyword">try</span>:
            <span class="py-src-variable">user</span>, <span class="py-src-variable">host</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">split</span>(<span class="py-src-string">'@'</span>, <span class="py-src-number">1</span>)
        <span class="py-src-keyword">except</span>:
            <span class="py-src-variable">user</span> = <span class="py-src-variable">user</span>.<span class="py-src-variable">strip</span>()
            <span class="py-src-variable">host</span> = <span class="py-src-string">'127.0.0.1'</span>
        <span class="py-src-variable">ret</span> = <span class="py-src-variable">finger</span>(<span class="py-src-variable">user</span>, <span class="py-src-variable">host</span>)
        <span class="py-src-variable">ret</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-keyword">lambda</span> <span class="py-src-variable">_</span>: <span class="py-src-string">&quot;Could not connect to remote host&quot;</span>)
        <span class="py-src-keyword">return</span> <span class="py-src-variable">ret</span>

    <span class="py-src-keyword">def</span> <span class="py-src-identifier">getUsers</span>(<span class="py-src-parameter">self</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">defer</span>.<span class="py-src-variable">succeed</span>([])

<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>)
<span class="py-src-variable">f</span> = <span class="py-src-variable">ProxyFingerService</span>()
<span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-number">7779</span>, <span class="py-src-variable">IFingerFactory</span>(<span class="py-src-variable">f</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>))
</pre><div class="caption">Source listing - <a href="listings/finger/fingerproxy.py"><span class="filename">listings/finger/fingerproxy.py</span></a></div></div></div><p><a href="../../howto/index.html">Index</a></p><span class="version">Version: 2.5.0</span></body></html>