<?xml version="1.0" encoding="utf-8"?>
<!-- generator="FeedCreator 1.7.2-ppt DokuWiki" -->
<?xml-stylesheet href="http://www.hodique.info/lib/exe/css.php?s=feed" type="text/css"?>
<rdf:RDF
    xmlns="http://purl.org/rss/1.0/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel rdf:about="http://www.hodique.info/feed.php">
        <title>Yann Hodique blog:2010:02:18</title>
        <description></description>
        <link>http://www.hodique.info/</link>
        <image rdf:resource="http://www.hodique.info/lib/images/favicon.ico" />
       <dc:date>2010-09-08T11:16:25+02:00</dc:date>
        <items>
            <rdf:Seq>
                <rdf:li rdf:resource="http://www.hodique.info/blog/2010/02/18/python_webservice_part_2_a_twistd_integration"/>
            </rdf:Seq>
        </items>
    </channel>
    <image rdf:about="http://www.hodique.info/lib/images/favicon.ico">
        <title>Yann Hodique</title>
        <link>http://www.hodique.info/</link>
        <url>http://www.hodique.info/lib/images/favicon.ico</url>
    </image>
    <item rdf:about="http://www.hodique.info/blog/2010/02/18/python_webservice_part_2_a_twistd_integration">
        <dc:format>text/html</dc:format>
        <dc:date>2010-02-19T00:01:46+02:00</dc:date>
        <title>Python Webservice, part 2 : a twistd integration</title>
        <link>http://www.hodique.info/blog/2010/02/18/python_webservice_part_2_a_twistd_integration</link>
        <description>


&lt;div class=&quot;level1&quot;&gt;


&lt;div class=&quot;styler styler-float-left&quot;&gt;
&lt;p&gt;
&lt;span class=&quot;vcard&quot;&gt;&lt;img src=&quot;http://www.hodique.info/lib/exe/fetch.php?hash=15d77b&amp;amp;cache=recache&amp;amp;media=http%3A%2F%2Fwww.gravatar.com%2Favatar.php%3Fgravatar_id%3Dd9b955e7af49b0cbfd68c15947b25012%26default%3Dhttp%253A%252F%252Fwww.hodique.info%252Flib%252Fexe%252Ffetch.php%253Fhash%253Dd44619%2526cache%253Drecache%2526media%253Dhttp%25253A%25252F%25252Fwww.hodique.info%25252F%25252Flib%25252Fplugins%25252Favatar%25252Fmonsterid.php%25253Fseed%25253Dd9b955e7af49b0cbfd68c15947b25012%252526size%25253D40%252526.png%26size%3D40%26rating%3DR%26.jpg&quot; class=&quot;media photo fn&quot; title=&quot;&amp;#x79;&amp;#x61;&amp;#x6e;&amp;#x6e;&amp;#x2e;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x69;&amp;#x71;&amp;#x75;&amp;#x65;&amp;#x40;&amp;#x67;&amp;#x6d;&amp;#x61;&amp;#x69;&amp;#x6c;&amp;#x2e;&amp;#x63;&amp;#x6f;&amp;#x6d;&quot; alt=&quot;&amp;#x79;&amp;#x61;&amp;#x6e;&amp;#x6e;&amp;#x2e;&amp;#x68;&amp;#x6f;&amp;#x64;&amp;#x69;&amp;#x71;&amp;#x75;&amp;#x65;&amp;#x40;&amp;#x67;&amp;#x6d;&amp;#x61;&amp;#x69;&amp;#x6c;&amp;#x2e;&amp;#x63;&amp;#x6f;&amp;#x6d;&quot; width=&quot;40&quot; height=&quot;40&quot; /&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;!-- SECTION &quot;Python Webservice, part 2 : a twistd integration&quot; [1-126] --&gt;
&lt;h2&gt;&lt;a name=&quot;twistd&quot; id=&quot;twistd&quot;&gt;Twistd&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
In my &lt;a href=&quot;http://www.hodique.info/blog/2010/02/17/python_webservice_part_1_a_twisted_solution&quot; class=&quot;wikilink1&quot; title=&quot;blog:2010:02:17:python_webservice_part_1_a_twisted_solution&quot;&gt;previous post&lt;/a&gt; I&amp;#039;ve explained how to generate a &lt;acronym title=&quot;Simple Object Access Protocol&quot;&gt;SOAP&lt;/acronym&gt; service from a WSDL file, and how to implement the required methods properly. A solution to run such a service is to use the Twisted Daemon, aka &lt;code&gt;twistd&lt;/code&gt;.
Though not needed, strictly speaking, it provides a nice &lt;a href=&quot;http://twistedmatrix.com/documents/current/core/howto/basics.html&quot; class=&quot;urlextern&quot; title=&quot;http://twistedmatrix.com/documents/current/core/howto/basics.html&quot;  rel=&quot;nofollow&quot;&gt;set of features&lt;/a&gt; aimed at easing complex applications development.
&lt;/p&gt;

&lt;p&gt;
In particular, it allows to write so-called &lt;a href=&quot;http://twistedmatrix.com/documents/current/core/howto/tap.html&quot; class=&quot;urlextern&quot; title=&quot;http://twistedmatrix.com/documents/current/core/howto/tap.html&quot;  rel=&quot;nofollow&quot;&gt;plugins&lt;/a&gt; that make it possible to just launch services in the following way:

&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;$ twistd &lt;span class=&quot;kw3&quot;&gt;echo&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
To achieve that, one has to create a file &lt;code&gt;twisted/plugins/echo.py&lt;/code&gt; accessible somewhere from the python path (that is, the &lt;code&gt;twisted&lt;/code&gt; directory should be a subdir of an element of the path).
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Twistd&quot; [127-1036] --&gt;
&lt;h2&gt;&lt;a name=&quot;manhole&quot; id=&quot;manhole&quot;&gt;Manhole&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

Twisted offers a nice service, that can be used to provide an inspection/debug interface for your main application. This is called &lt;a href=&quot;http://twistedmatrix.com/documents/9.0.0/api/twisted.manhole.html&quot; class=&quot;urlextern&quot; title=&quot;http://twistedmatrix.com/documents/9.0.0/api/twisted.manhole.html&quot;  rel=&quot;nofollow&quot;&gt;manhole&lt;/a&gt; and provides a python interpreter interface. This way you can just telnet/ssh the manhole, and execute appropriate commands to introspect the current state of the application, or put it in the desired state.
&lt;/p&gt;

&lt;p&gt;
A nice example of a really useful function to run from the manhole service is the &lt;a href=&quot;http://twistedmatrix.com/documents/9.0.0/api/twisted.python.rebuild.html&quot; class=&quot;urlextern&quot; title=&quot;http://twistedmatrix.com/documents/9.0.0/api/twisted.python.rebuild.html&quot;  rel=&quot;nofollow&quot;&gt;rebuild&lt;/a&gt; one. It tries very hard to provide in-place reloading of code (and corresponding objects). Don&amp;#039;t expect any wonder here, it will fail in some corner cases. Still, it proves really useful most of the time, and helps a lot not restarting the server every now and then.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Manhole&quot; [1037-1910] --&gt;
&lt;h2&gt;&lt;a name=&quot;example&quot; id=&quot;example&quot;&gt;Example&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

Here is a fully working example of a twistd plugin for the Echo service, with a functional manhole service in addition.
&lt;/p&gt;
&lt;pre class=&quot;code python&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; zope.&lt;span class=&quot;me1&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; implements
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; usage
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;python&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;rebuild&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; rebuild
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;plugin&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; IPlugin
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;application&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; IServiceMaker, MultiService
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;application&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;internet&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; TCPServer
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;web&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; Site
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;web&lt;/span&gt;.&lt;span class=&quot;kw3&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; Resource
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; twisted.&lt;span class=&quot;me1&quot;&gt;conch&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;manhole_tap&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; makeService &lt;span class=&quot;kw1&quot;&gt;as&lt;/span&gt; makeConsoleService
&amp;nbsp;
&lt;span class=&quot;kw1&quot;&gt;from&lt;/span&gt; EchoImpl &lt;span class=&quot;kw1&quot;&gt;import&lt;/span&gt; EchoService
&amp;nbsp;
&lt;span class=&quot;kw1&quot;&gt;class&lt;/span&gt; EchoOptions&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;usage.&lt;span class=&quot;me1&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;:
    optParameters = &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;port&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;8080&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;main port&amp;quot;&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,
                     &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;service-port&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;s&amp;quot;&lt;/span&gt;, &lt;span class=&quot;nu0&quot;&gt;8081&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;service port&amp;quot;&lt;/span&gt;, &lt;span class=&quot;kw2&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;,
                     &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;service-users&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;u&amp;quot;&lt;/span&gt;, &lt;span class=&quot;st0&quot;&gt;&amp;quot;/etc/passwd&amp;quot;&lt;/span&gt;,
                      &lt;span class=&quot;st0&quot;&gt;&amp;quot;The path to a passwd-like authentication file&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw1&quot;&gt;class&lt;/span&gt; EchoServiceMaker&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;:
    implements&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;IServiceMaker, IPlugin&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    tapname = &lt;span class=&quot;st0&quot;&gt;&amp;quot;echo&amp;quot;&lt;/span&gt;
    description = &lt;span class=&quot;st0&quot;&gt;&amp;quot;Sample Echo service&amp;quot;&lt;/span&gt;
    options = EchoOptions
&amp;nbsp;
    &lt;span class=&quot;kw1&quot;&gt;def&lt;/span&gt; makeService&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;self&lt;/span&gt;, options&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;:
        &lt;span class=&quot;co1&quot;&gt;# Create Service&lt;/span&gt;
        srv = EchoService&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;
        root = Resource&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span class=&quot;co1&quot;&gt;# we'll serve Echo at http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;/echo&lt;/span&gt;
        root.&lt;span class=&quot;me1&quot;&gt;putChild&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'echo'&lt;/span&gt;, srv&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
        siteFactory = Site&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;root&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;
        echo_service = TCPServer&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;options&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'port'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;, siteFactory&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
        console_service = makeConsoleService&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;
            &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;telnetPort&amp;quot;&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;options&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'service-port'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,
             &lt;span class=&quot;st0&quot;&gt;&amp;quot;sshPort&amp;quot;&lt;/span&gt;: &lt;span class=&quot;kw2&quot;&gt;None&lt;/span&gt;,
             &lt;span class=&quot;st0&quot;&gt;&amp;quot;namespace&amp;quot;&lt;/span&gt;: &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;service&amp;quot;&lt;/span&gt;: srv,
                           &lt;span class=&quot;st0&quot;&gt;&amp;quot;rebuild&amp;quot;&lt;/span&gt;: rebuild&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;,
             &lt;span class=&quot;st0&quot;&gt;&amp;quot;passwd&amp;quot;&lt;/span&gt;: options&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;'service-users'&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;
        svc = MultiService&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
        echo_service.&lt;span class=&quot;me1&quot;&gt;setServiceParent&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;svc&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
        console_service.&lt;span class=&quot;me1&quot;&gt;setServiceParent&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;svc&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&amp;nbsp;
        &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; svc
&amp;nbsp;
serviceMaker = EchoServiceMaker&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The code is hopefully rather straightforward. It should be noted that the manhole service (created by the &lt;code&gt;makeConsoleService()&lt;/code&gt; call) needs to know about a set of objects (the “namespace” key). Those objects are the roots for everything accessible from the service. Here, the main service object (the &lt;code&gt;srv&lt;/code&gt; object) is available to the manhole under the name &lt;code&gt;service&lt;/code&gt;. Here is how it can be used:
&lt;/p&gt;
&lt;pre class=&quot;code shell&quot;&gt;$ telnet localhost 8081
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Username: yann
Password: x
&amp;nbsp;
&amp;gt;&amp;gt;&amp;gt; print service
&amp;lt;EchoImpl.EchoService object at 0x2fc8c10&amp;gt;
&amp;gt;&amp;gt;&amp;gt;&lt;/pre&gt;

&lt;p&gt;
Hint: the password is really &amp;#039;x&amp;#039;, as I&amp;#039;m using /etc/passwd by default, which contains &amp;#039;x&amp;#039; for every “password” field, since the real passwords are in /etc/shadow.
Convenient for a dev deployment ;)
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;http://www.hodique.info/tags/python&quot; class=&quot;wikilink1&quot; title=&quot;tags:python&quot; rel=&quot;tag&quot;&gt;python&lt;/a&gt;,
	&lt;a href=&quot;http://www.hodique.info/tags/code&quot; class=&quot;wikilink1&quot; title=&quot;tags:code&quot; rel=&quot;tag&quot;&gt;code&lt;/a&gt;,
	&lt;a href=&quot;http://www.hodique.info/tags/twisted&quot; class=&quot;wikilink1&quot; title=&quot;tags:twisted&quot; rel=&quot;tag&quot;&gt;twisted&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Example&quot; [1911-] --&gt;&lt;span class=&quot;plugin_feedmod_comments&quot;&gt;
  &lt;a href=&quot;http://www.hodique.info/blog/2010/02/18/python_webservice_part_2_a_twistd_integration#discussion__section&quot; title=&quot;Read or add comments to this article&quot;&gt;Read or add comments to this article&lt;/a&gt;
&lt;/span&gt;
</description>
    </item>
</rdf:RDF>
