Sophie

Sophie

distrib > Mageia > 4 > x86_64 > by-pkgid > c3732731228538f6126cae930c10ad71 > files > 200

python-pyro4-4.21-3.mga4.noarch.rpm



<!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">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Servers: publishing objects &mdash; Pyro 4.21 documentation</title>
    
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '4.21',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="Pyro 4.21 documentation" href="index.html" />
    <link rel="next" title="Name Server" href="nameserver.html" />
    <link rel="prev" title="Clients: Calling remote objects" href="clientcode.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="nameserver.html" title="Name Server"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="clientcode.html" title="Clients: Calling remote objects"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">Pyro 4.21 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="servers-publishing-objects">
<h1>Servers: publishing objects<a class="headerlink" href="#servers-publishing-objects" title="Permalink to this headline">¶</a></h1>
<p>This chapter explains how you write code that publishes objects to be remotely accessible.
These objects are then called <em>Pyro objects</em> and the program that provides them,
is often called a <em>server</em> program.</p>
<p>(The program that calls the objects is usually called the <em>client</em>.
Both roles can be mixed in a single program.)</p>
<p>Make sure you are familiar with Pyro&#8217;s <a class="reference internal" href="tutorials.html#keyconcepts"><em>Key concepts</em></a> before reading on.</p>
<div class="admonition-see-also admonition seealso">
<p class="first admonition-title">See also</p>
<p class="last"><a class="reference internal" href="config.html"><em>Configuring Pyro</em></a> for several config items that you can use to tweak various server side aspects.</p>
</div>
<div class="section" id="pyro-daemon-publishing-pyro-objects">
<span id="publish-objects"></span><h2>Pyro Daemon: publishing Pyro objects<a class="headerlink" href="#pyro-daemon-publishing-pyro-objects" title="Permalink to this headline">¶</a></h2>
<p>To publish a regular Python object and turn it into a Pyro object,
you have to tell Pyro about it. After that, your code has to tell Pyro to start listening for incoming
requests and to process them. Both are handled by the <em>Pyro daemon</em>.</p>
<p>In its most basic form, you create one or more objects that you want to publish as Pyro objects,
you create a daemon, register the object(s) with the daemon, and then enter the daemon&#8217;s request loop:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>

<span class="k">class</span> <span class="nc">MyPyroThing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="n">thing</span><span class="o">=</span><span class="n">MyPyroThing</span><span class="p">()</span>
<span class="n">daemon</span><span class="o">=</span><span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="p">()</span>
<span class="n">uri</span><span class="o">=</span><span class="n">daemon</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span>
<span class="k">print</span> <span class="n">uri</span>
<span class="n">daemon</span><span class="o">.</span><span class="n">requestLoop</span><span class="p">()</span>
</pre></div>
</div>
<p>After printing the uri, the server sits waiting for requests.
The uri that is being printed looks a bit like this: <tt class="docutils literal"><span class="pre">PYRO:obj_dcf713ac20ce4fb2a6e72acaeba57dfd&#64;localhost:51850</span></tt>
It can be used in a <em>client</em> program to create a proxy and access your Pyro object with.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>You can publish any regular Python object as a Pyro object.
However since Pyro adds a few Pyro-specific attributes to the object, you can&#8217;t use:</p>
<ul class="last simple">
<li>types that don&#8217;t allow custom attributes, such as the builtin types (<tt class="docutils literal"><span class="pre">str</span></tt> and <tt class="docutils literal"><span class="pre">int</span></tt> for instance)</li>
<li>types with <tt class="docutils literal"><span class="pre">__slots__</span></tt> (a possible way around this is to add Pyro&#8217;s custom attributes to your <tt class="docutils literal"><span class="pre">__slots__</span></tt>, but that isn&#8217;t very nice)</li>
</ul>
</div>
<div class="section" id="oneliner-pyro-object-publishing">
<h3>Oneliner Pyro object publishing<a class="headerlink" href="#oneliner-pyro-object-publishing" title="Permalink to this headline">¶</a></h3>
<p>Ok not really a one-liner, but one statement: use <tt class="docutils literal"><span class="pre">serveSimple</span></tt> to publish a dict of objects and start Pyro&#8217;s request loop.
The code above could also be written as:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>

<span class="k">class</span> <span class="nc">MyPyroThing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="o">.</span><span class="n">serveSimple</span><span class="p">(</span>
    <span class="p">{</span>
        <span class="n">MyPyroThing</span><span class="p">():</span> <span class="bp">None</span>
    <span class="p">},</span>
    <span class="n">ns</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Verbose is set to True because you want it to print out the generated random object uri, otherwise
there is no way to connect to your object. You can also choose to provide object names yourself,
to use or not use the name server, etc. See <a class="reference internal" href="api/core.html#Pyro4.core.Daemon.serveSimple" title="Pyro4.core.Daemon.serveSimple"><tt class="xref py py-func docutils literal"><span class="pre">Pyro4.core.Daemon.serveSimple()</span></tt></a>.</p>
<p>Note that the amount of options you can provide is quite limited.
If you want to control the way the Pyro daemon is constructed, you have to do that by setting
the appropriate config options before calling <tt class="docutils literal"><span class="pre">serveSimple</span></tt>.
Or you can create a daemon object yourself with the right arguments,
and pass that to <tt class="docutils literal"><span class="pre">serveSimple</span></tt> so that it doesn&#8217;t create a default daemon itself.
Because they are so frequently used, <tt class="docutils literal"><span class="pre">serveSimple</span></tt> has a <tt class="docutils literal"><span class="pre">host</span></tt> and <tt class="docutils literal"><span class="pre">port</span></tt> parameter
that you can use to control the host and port of the daemon that it creates (useful if you
want to make it run on something else as localhost).</p>
</div>
<div class="section" id="creating-a-daemon">
<h3>Creating a Daemon<a class="headerlink" href="#creating-a-daemon" title="Permalink to this headline">¶</a></h3>
<p>Pyro&#8217;s daemon is <a class="reference internal" href="api/core.html#Pyro4.core.Daemon" title="Pyro4.core.Daemon"><tt class="xref py py-class docutils literal"><span class="pre">Pyro4.core.Daemon</span></tt></a> and you can also access it by its shortcut <tt class="docutils literal"><span class="pre">Pyro4.Daemon</span></tt>.
It has a few optional arguments when you create it:</p>
<dl class="function">
<dt id="Daemon">
<tt class="descname">Daemon</tt><big>(</big><span class="optional">[</span><em>host=None</em>, <em>port=0</em>, <em>unixsocket=None</em>, <em>nathost=None</em>, <em>natport=None</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#Daemon" title="Permalink to this definition">¶</a></dt>
<dd><p>Create a new Pyro daemon.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>host</strong> (<em>str or None</em>) &#8211; the hostname or IP address to bind the server on. Default is <tt class="docutils literal"><span class="pre">None</span></tt> which means it uses the configured default (which is localhost).</li>
<li><strong>port</strong> (<em>int</em>) &#8211; port to bind the server on. Defaults to 0, which means to pick a random port.</li>
<li><strong>unixsocket</strong> (<em>str or None</em>) &#8211; the name of a Unix domain socket to use instead of a TCP/IP socket. Default is <tt class="docutils literal"><span class="pre">None</span></tt> (don&#8217;t use).</li>
<li><strong>nathost</strong> &#8211; hostname to use in published addresses (useful when running behind a NAT firewall/router). Default is <tt class="docutils literal"><span class="pre">None</span></tt> which means to just use the normal host.
For more details about NAT, see <a class="reference internal" href="tipstricks.html#nat-router"><em>Pyro behind a NAT router/firewall</em></a>.</li>
<li><strong>natport</strong> &#8211; port to use in published addresses (useful when running behind a NAT firewall/router). If you use 0 here,
Pyro will replace the NAT-port by the internal port number to facilitate one-to-one NAT port mappings.</li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd></dl>

</div>
<div class="section" id="registering-objects">
<h3>Registering objects<a class="headerlink" href="#registering-objects" title="Permalink to this headline">¶</a></h3>
<p>Every object you want to publish as a Pyro object needs to be registered with the daemon.
You can let Pyro choose a unique object id for you, or provide a more readable one yourself.</p>
<dl class="method">
<dt id="Daemon.register">
<tt class="descclassname">Daemon.</tt><tt class="descname">register</tt><big>(</big><em>obj</em><span class="optional">[</span>, <em>objectId=None</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#Daemon.register" title="Permalink to this definition">¶</a></dt>
<dd><p>Registers an object with the daemon to turn it into a Pyro object.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>obj</strong> &#8211; the object to register</li>
<li><strong>objectId</strong> (<em>str or None</em>) &#8211; optional custom object id (must be unique). Default is to let Pyro create one for you.</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">an uri for the object</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last"><a class="reference internal" href="api/core.html#Pyro4.core.URI" title="Pyro4.core.URI"><tt class="xref py py-class docutils literal"><span class="pre">Pyro4.core.URI</span></tt></a></p>
</td>
</tr>
</tbody>
</table>
</dd></dl>

<p>It is important to do something with the uri that is returned: it is the key to access the Pyro object.
You can save it somewhere, or perhaps print it to the screen.
The point is, your client programs need it to be able to access your object (they need to create a proxy with it).</p>
<p>Maybe the easiest thing is to store it in the Pyro name server.
That way it is almost trivial for clients to obtain the proper uri and connect to your object.
See <a class="reference internal" href="nameserver.html"><em>Name Server</em></a> for more information.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you ever need to create a new uri for an object, you can use <a class="reference internal" href="api/core.html#Pyro4.core.Daemon.uriFor" title="Pyro4.core.Daemon.uriFor"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.core.Daemon.uriFor()</span></tt></a>.
The reason this method exists on the daemon is because an uri contains location information and
the daemon is the one that knows about this.</p>
</div>
<div class="section" id="intermission-example-1-server-and-client-not-using-name-server">
<h4>Intermission: Example 1: server and client not using name server<a class="headerlink" href="#intermission-example-1-server-and-client-not-using-name-server" title="Permalink to this headline">¶</a></h4>
<p>A little code example that shows the very basics of creating a daemon and publishing a Pyro object with it.
Server code:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>

<span class="k">class</span> <span class="nc">Thing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">arg</span><span class="o">*</span><span class="mi">2</span>

<span class="c"># ------ normal code ------</span>
<span class="n">daemon</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="p">()</span>
<span class="n">uri</span> <span class="o">=</span> <span class="n">daemon</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">Thing</span><span class="p">())</span>
<span class="k">print</span> <span class="s">&quot;uri=&quot;</span><span class="p">,</span><span class="n">uri</span>
<span class="n">daemon</span><span class="o">.</span><span class="n">requestLoop</span><span class="p">()</span>

<span class="c"># ------ alternatively, using serveSimple -----</span>
<span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="o">.</span><span class="n">serveSimple</span><span class="p">(</span>
    <span class="p">{</span>
        <span class="n">Thing</span><span class="p">():</span> <span class="bp">None</span>
    <span class="p">},</span>
    <span class="n">ns</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Client code example to connect to this object:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>
<span class="c"># use the URI that the server printed:</span>
<span class="n">uri</span> <span class="o">=</span> <span class="s">&quot;PYRO:obj_b2459c80671b4d76ac78839ea2b0fb1f@localhost:49383&quot;</span>
<span class="n">thing</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Proxy</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
<span class="k">print</span> <span class="n">thing</span><span class="o">.</span><span class="n">method</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>   <span class="c"># prints 84</span>
</pre></div>
</div>
<p>With correct additional parameters &#8211;described elsewhere in this chapter&#8211; you can control on which port the daemon is listening,
on what network interface (ip address/hostname), what the object id is, etc.</p>
</div>
<div class="section" id="intermission-example-2-server-and-client-with-name-server">
<h4>Intermission: Example 2: server and client, with name server<a class="headerlink" href="#intermission-example-2-server-and-client-with-name-server" title="Permalink to this headline">¶</a></h4>
<p>A little code example that shows the very basics of creating a daemon and publishing a Pyro object with it,
this time using the name server for easier object lookup.
Server code:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>

<span class="k">class</span> <span class="nc">Thing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">arg</span><span class="o">*</span><span class="mi">2</span>

<span class="c"># ------ normal code ------</span>
<span class="n">daemon</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="p">()</span>
<span class="n">ns</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">locateNS</span><span class="p">()</span>
<span class="n">uri</span> <span class="o">=</span> <span class="n">daemon</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">Thing</span><span class="p">())</span>
<span class="n">ns</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="s">&quot;mythingy&quot;</span><span class="p">,</span> <span class="n">uri</span><span class="p">)</span>
<span class="n">daemon</span><span class="o">.</span><span class="n">requestLoop</span><span class="p">()</span>

<span class="c"># ------ alternatively, using serveSimple -----</span>
<span class="n">Pyro4</span><span class="o">.</span><span class="n">Daemon</span><span class="o">.</span><span class="n">serveSimple</span><span class="p">(</span>
    <span class="p">{</span>
        <span class="n">Thing</span><span class="p">():</span> <span class="s">&quot;mythingy&quot;</span>
    <span class="p">},</span>
    <span class="n">ns</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<p>Client code example to connect to this object:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">Pyro4</span>
<span class="n">thing</span> <span class="o">=</span> <span class="n">Pyro4</span><span class="o">.</span><span class="n">Proxy</span><span class="p">(</span><span class="s">&quot;PYRONAME:mythingy&quot;</span><span class="p">)</span>
<span class="k">print</span> <span class="n">thing</span><span class="o">.</span><span class="n">method</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>   <span class="c"># prints 84</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="unregistering-objects">
<h3>Unregistering objects<a class="headerlink" href="#unregistering-objects" title="Permalink to this headline">¶</a></h3>
<p>When you no longer want to publish an object, you need to unregister it from the daemon:</p>
<dl class="method">
<dt id="Daemon.unregister">
<tt class="descclassname">Daemon.</tt><tt class="descname">unregister</tt><big>(</big><em>objectOrId</em><big>)</big><a class="headerlink" href="#Daemon.unregister" title="Permalink to this definition">¶</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>objectOrId</strong> (<em>object itself or its id string</em>) &#8211; the object to unregister</td>
</tr>
</tbody>
</table>
</dd></dl>

</div>
<div class="section" id="running-the-request-loop">
<h3>Running the request loop<a class="headerlink" href="#running-the-request-loop" title="Permalink to this headline">¶</a></h3>
<p>Once you&#8217;ve registered your Pyro object you&#8217;ll need to run the daemon&#8217;s request loop to make
Pyro wait for incoming requests.</p>
<dl class="method">
<dt id="Daemon.requestLoop">
<tt class="descclassname">Daemon.</tt><tt class="descname">requestLoop</tt><big>(</big><span class="optional">[</span><em>loopCondition</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#Daemon.requestLoop" title="Permalink to this definition">¶</a></dt>
<dd><table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>loopCondition</strong> &#8211; optional callable returning a boolean, if it returns False the request loop will be aborted and the call returns</td>
</tr>
</tbody>
</table>
</dd></dl>

<p>This is Pyro&#8217;s event loop and it will take over your program until it returns (it might never.)
If this is not what you want, you can control it a tiny bit with the <tt class="docutils literal"><span class="pre">loopCondition</span></tt>, or read the next paragraph.</p>
</div>
<div class="section" id="integrating-pyro-in-your-own-event-loop">
<h3>Integrating Pyro in your own event loop<a class="headerlink" href="#integrating-pyro-in-your-own-event-loop" title="Permalink to this headline">¶</a></h3>
<p>If you want to use a Pyro daemon in your own program that already has an event loop (aka main loop),
you can&#8217;t simply call <tt class="docutils literal"><span class="pre">requestLoop</span></tt> because that will block your program.
A daemon provides a few tools to let you integrate it into your own event loop:</p>
<ul class="simple">
<li><tt class="xref py py-attr docutils literal"><span class="pre">Pyro4.core.Daemon.sockets</span></tt> - list of all socket objects used by the daemon, to inject in your own event loop</li>
<li><a class="reference internal" href="api/core.html#Pyro4.core.Daemon.events" title="Pyro4.core.Daemon.events"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.core.Daemon.events()</span></tt></a> - method to call from your own event loop when Pyro needs to process requests. Argument is a list of sockets that triggered.</li>
</ul>
<p>For more details and example code, see the <tt class="file docutils literal"><span class="pre">eventloop</span></tt> and <tt class="file docutils literal"><span class="pre">gui_eventloop</span></tt> examples.
They show how to use Pyro including a name server, in your own event loop, and also possible ways
to use Pyro from within a GUI program with its own event loop.</p>
</div>
<div class="section" id="cleaning-up">
<h3>Cleaning up<a class="headerlink" href="#cleaning-up" title="Permalink to this headline">¶</a></h3>
<p>To clean up the daemon itself (release its resources) either use the daemon object
as a context manager in a <tt class="docutils literal"><span class="pre">with</span></tt> statement, or manually call <a class="reference internal" href="api/core.html#Pyro4.core.Daemon.close" title="Pyro4.core.Daemon.close"><tt class="xref py py-meth docutils literal"><span class="pre">Pyro4.core.Daemon.close()</span></tt></a>.</p>
</div>
</div>
<div class="section" id="autoproxying">
<h2>Autoproxying<a class="headerlink" href="#autoproxying" title="Permalink to this headline">¶</a></h2>
<p>Pyro will automatically take care of any Pyro objects that you pass around through remote method calls.
It will replace them by a proxy automatically, so the receiving side can call methods on it and be
sure to talk to the remote object instead of a local copy. There is no need to create a proxy object manually.
All you have to do is to register the new object with the appropriate daemon:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">some_pyro_method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="n">thing</span><span class="o">=</span><span class="n">SomethingNew</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">_pyroDaemon</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">thing</span>    <span class="c"># just return it, no need to return a proxy</span>
</pre></div>
</div>
<p>This feature can be enabled or disabled by a config item, see <a class="reference internal" href="config.html"><em>Configuring Pyro</em></a>.
(it is on by default). If it is off, a copy of the object itself is returned,
and the client won&#8217;t be able to interact with the actual new Pyro object in the server.
There is a <tt class="file docutils literal"><span class="pre">autoproxy</span></tt> example that shows the use of this feature,
and several other examples also make use of it.</p>
<p>Note that when using the marshal serializer, this feature doesn&#8217;t work. You have to use
one of the other serializers to use autoproxying.</p>
</div>
<div class="section" id="server-types-and-object-concurrency-model">
<h2>Server types and Object concurrency model<a class="headerlink" href="#server-types-and-object-concurrency-model" title="Permalink to this headline">¶</a></h2>
<p>Pyro supports multiple server types (the way the Daemon listens for requests). Select the
desired type by setting the <tt class="docutils literal"><span class="pre">SERVERTYPE</span></tt> config item. It depends very much on what you
are doing in your Pyro objects what server type is most suitable. For instance, if your Pyro
object does a lot of I/O, it may benefit from the parallelism provided by the thread pool server.
However if it is doing a lot of CPU intensive calculations, the multiplexed server may be more
appropriate. If in doubt, go with the default setting.</p>
<ol class="arabic">
<li><dl class="first docutils">
<dt>threaded server (servertype <tt class="docutils literal"><span class="pre">&quot;threaded&quot;</span></tt>, this is the default)</dt>
<dd><p class="first last">This server uses a thread pool to handle incoming proxy connections.
The size of the pool is configurable via various config items.
Every proxy on a client that connects to the daemon will be assigned to a thread to handle
the remote method calls. This way multiple calls can potentially be processed concurrently.
This means your Pyro object must be <em>thread-safe</em>! If you access a shared resource from
your Pyro object you may need to take thread locking measures such as using Queues.
If the thread pool is too small for the number of proxy connections, new proxy connections will
be put to wait until another proxy disconnects from the server.</p>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>multiplexed server (servertype <tt class="docutils literal"><span class="pre">&quot;multiplex&quot;</span></tt>)</dt>
<dd><p class="first last">This server uses a select (or poll, if available) based connection multiplexer to process
all remote method calls sequentially. No threads are used in this server. It means
only one method call is running at a time, so if it takes a while to complete, all other
calls are waiting for their turn (even when they are from different proxies).</p>
</dd>
</dl>
</li>
</ol>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If the <tt class="docutils literal"><span class="pre">ONEWAY_THREADED</span></tt> config item is enabled (it is by default), <em>oneway</em> method calls will
be executed in a separate worker thread, regardless of the server type you&#8217;re using.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">It must be pretty obvious but the following is a very important concept so it is repeated
once more to be 100% clear:
Currently, you register <em>objects</em> with Pyro, not <em>classes</em>. This means remote method calls
to a certain Pyro object always run on the single instance that you registered with Pyro.</p>
</div>
<p><em>When to choose which server type?</em>
With the threadpool server at least you have a chance to achieve concurrency, and
you don&#8217;t have to worry much about blocking I/O in your remote calls. The usual
trouble with using threads in Python still applies though:
Python threads don&#8217;t run concurrently unless they release the <abbr title="Global Interpreter Lock">GIL</abbr>.
If they don&#8217;t, you will still hang your server process.
For instance if a particular piece of your code doesn&#8217;t release the <abbr title="Global Interpreter Lock">GIL</abbr> during
a longer computation, the other threads will remain asleep waiting to acquire the <abbr title="Global Interpreter Lock">GIL</abbr>. One of these threads may be
the Pyro server loop and then your whole Pyro server will become unresponsive.
Doing I/O usually means the <abbr title="Global Interpreter Lock">GIL</abbr> is released.
Some C extension modules also release it when doing their work. So, depending on your situation, not all hope is lost.</p>
<p>With the multiplexed server you don&#8217;t have threading problems: everything runs in a single main thread.
This means your requests are processed sequentially, but it&#8217;s easier to make the Pyro server
unresponsive. Any operation that uses blocking I/O or a long-running computation will block
all remote calls until it has completed.</p>
</div>
<div class="section" id="serialization">
<h2>Serialization<a class="headerlink" href="#serialization" title="Permalink to this headline">¶</a></h2>
<p>Pyro will serialize the objects that you pass to the remote methods, so they can be sent across
a network connection. Depending on the serializer that is being used for your Pyro server,
there will be some limitations on what objects you can use, and what serialization format is
required of the clients that connect to your server.</p>
<p>You select the serializer to be used by setting the <tt class="docutils literal"><span class="pre">SERIALIZER</span></tt> config item. (See the <a class="reference internal" href="config.html"><em>Configuring Pyro</em></a> chapter).
See <a class="reference internal" href="clientcode.html#object-serialization"><em>Serialization</em></a> for more details.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Since Pyro 4.20 the default serializer is &#8220;<tt class="docutils literal"><span class="pre">serpent</span></tt>&#8221;. It used to be &#8220;<tt class="docutils literal"><span class="pre">pickle</span></tt>&#8221; in older versions.</p>
</div>
</div>
<div class="section" id="other-features">
<h2>Other features<a class="headerlink" href="#other-features" title="Permalink to this headline">¶</a></h2>
<div class="section" id="attributes-added-to-pyro-objects">
<h3>Attributes added to Pyro objects<a class="headerlink" href="#attributes-added-to-pyro-objects" title="Permalink to this headline">¶</a></h3>
<p>The following attributes will be added your object if you register it as a Pyro object:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">_pyroId</span></tt> - the unique id of this object (a <tt class="docutils literal"><span class="pre">str</span></tt>)</li>
<li><tt class="docutils literal"><span class="pre">_pyroDaemon</span></tt> - a reference to the <a class="reference internal" href="api/core.html#Pyro4.core.Daemon" title="Pyro4.core.Daemon"><tt class="xref py py-class docutils literal"><span class="pre">Pyro4.core.Daemon</span></tt></a> object that contains this object</li>
</ul>
<p>Even though they start with an underscore (and are private, in a way),
you can use them as you so desire. As long as you don&#8217;t modify them!
The daemon reference for instance is useful to register newly created objects with,
to avoid the need of storing a global daemon object somewhere.</p>
<p>These attributes will be removed again once you unregister the object.</p>
</div>
<div class="section" id="network-adapter-binding">
<h3>Network adapter binding<a class="headerlink" href="#network-adapter-binding" title="Permalink to this headline">¶</a></h3>
<p>All Pyro daemons bind on localhost by default. This is because of security reasons.
This means only processes on the same machine have access to your Pyro objects.
If you want to make them available for remote machines, you&#8217;ll have to tell Pyro on what
network interface address it must bind the daemon.</p>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Read chapter <a class="reference internal" href="security.html"><em>Security</em></a> before exposing Pyro objects to remote machines!</p>
</div>
<p>There are a few ways to tell Pyro what network address it needs to use.
You can set a global config item <tt class="docutils literal"><span class="pre">HOST</span></tt>, or pass a <tt class="docutils literal"><span class="pre">host</span></tt> parameter to the constructor of a Daemon,
or use a command line argument if you&#8217;re dealing with the name server.
For more details, refer to the chapters in this manual about the relevant Pyro components.</p>
<p>Pyro provides a couple of utility functions to help you with finding the appropriate IP address
to bind your servers on if you want to make them publicly accessible:</p>
<ul class="simple">
<li><a class="reference internal" href="api/util.html#Pyro4.socketutil.getIpAddress" title="Pyro4.socketutil.getIpAddress"><tt class="xref py py-func docutils literal"><span class="pre">Pyro4.socketutil.getIpAddress()</span></tt></a></li>
<li><a class="reference internal" href="api/util.html#Pyro4.socketutil.getInterfaceAddress" title="Pyro4.socketutil.getInterfaceAddress"><tt class="xref py py-func docutils literal"><span class="pre">Pyro4.socketutil.getInterfaceAddress()</span></tt></a></li>
</ul>
</div>
<div class="section" id="daemon-pyro-interface">
<h3>Daemon Pyro interface<a class="headerlink" href="#daemon-pyro-interface" title="Permalink to this headline">¶</a></h3>
<p>A rather interesting aspect of Pyro&#8217;s Daemon is that it (partly) is a Pyro object itself.
This means it exposes a couple of remote methods that you can also invoke yourself if you want.
The object exposed is <a class="reference internal" href="api/core.html#Pyro4.core.DaemonObject" title="Pyro4.core.DaemonObject"><tt class="xref py py-class docutils literal"><span class="pre">Pyro4.core.DaemonObject</span></tt></a> (as you can see it is a bit limited still).</p>
<p>You access this object by creating a proxy for the <tt class="docutils literal"><span class="pre">&quot;Pyro.Daemon&quot;</span></tt> object. That is a reserved
object name. You can use it directly but it is preferable to use the constant
<tt class="docutils literal"><span class="pre">Pyro4.constants.DAEMON_NAME</span></tt>. An example follows that accesses the daemon object from a running name server:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">Pyro4</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">daemon</span><span class="o">=</span><span class="n">Pyro4</span><span class="o">.</span><span class="n">Proxy</span><span class="p">(</span><span class="s">&quot;PYRO:&quot;</span><span class="o">+</span><span class="n">Pyro4</span><span class="o">.</span><span class="n">constants</span><span class="o">.</span><span class="n">DAEMON_NAME</span><span class="o">+</span><span class="s">&quot;@localhost:9090&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">daemon</span><span class="o">.</span><span class="n">ping</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">daemon</span><span class="o">.</span><span class="n">registered</span><span class="p">()</span>
<span class="go">[&#39;Pyro.NameServer&#39;, &#39;Pyro.Daemon&#39;]</span>
</pre></div>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="index.html">
              <img class="logo" src="_static/pyro.png" alt="Logo"/>
            </a></p>
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Servers: publishing objects</a><ul>
<li><a class="reference internal" href="#pyro-daemon-publishing-pyro-objects">Pyro Daemon: publishing Pyro objects</a><ul>
<li><a class="reference internal" href="#oneliner-pyro-object-publishing">Oneliner Pyro object publishing</a></li>
<li><a class="reference internal" href="#creating-a-daemon">Creating a Daemon</a></li>
<li><a class="reference internal" href="#registering-objects">Registering objects</a><ul>
<li><a class="reference internal" href="#intermission-example-1-server-and-client-not-using-name-server">Intermission: Example 1: server and client not using name server</a></li>
<li><a class="reference internal" href="#intermission-example-2-server-and-client-with-name-server">Intermission: Example 2: server and client, with name server</a></li>
</ul>
</li>
<li><a class="reference internal" href="#unregistering-objects">Unregistering objects</a></li>
<li><a class="reference internal" href="#running-the-request-loop">Running the request loop</a></li>
<li><a class="reference internal" href="#integrating-pyro-in-your-own-event-loop">Integrating Pyro in your own event loop</a></li>
<li><a class="reference internal" href="#cleaning-up">Cleaning up</a></li>
</ul>
</li>
<li><a class="reference internal" href="#autoproxying">Autoproxying</a></li>
<li><a class="reference internal" href="#server-types-and-object-concurrency-model">Server types and Object concurrency model</a></li>
<li><a class="reference internal" href="#serialization">Serialization</a></li>
<li><a class="reference internal" href="#other-features">Other features</a><ul>
<li><a class="reference internal" href="#attributes-added-to-pyro-objects">Attributes added to Pyro objects</a></li>
<li><a class="reference internal" href="#network-adapter-binding">Network adapter binding</a></li>
<li><a class="reference internal" href="#daemon-pyro-interface">Daemon Pyro interface</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="clientcode.html"
                        title="previous chapter">Clients: Calling remote objects</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="nameserver.html"
                        title="next chapter">Name Server</a></p>
<div id="searchbox" style="display: none">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
    <p class="searchtip" style="font-size: 90%">
    Enter search terms or a module, class or function name.
    </p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="nameserver.html" title="Name Server"
             >next</a> |</li>
        <li class="right" >
          <a href="clientcode.html" title="Clients: Calling remote objects"
             >previous</a> |</li>
        <li><a href="index.html">Pyro 4.21 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
        &copy; Copyright Irmen de Jong.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
    </div>
  </body>
</html>