logilab-common /

# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact --
# This file is part of logilab-common.
# logilab-common is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option) any
# later version.
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
# You should have received a copy of the GNU Lesser General Public License along
# with logilab-common.  If not, see <>.
"""Python Remote Object utilities

Main functions available:

* `register_object` to expose arbitrary object through pyro using delegation
  approach and register it in the nameserver.
* `ns_unregister` unregister an object identifier from the nameserver.
* `ns_get_proxy` get a pyro proxy from a nameserver object identifier.

__docformat__ = "restructuredtext en"

import logging
import tempfile

from Pyro import core, naming, errors, util, config

_LOGGER = logging.getLogger('pyro')
_MARKER = object()

config.PYRO_STORAGE = tempfile.gettempdir()

def ns_group_and_id(idstr, defaultnsgroup=_MARKER):
        nsgroup, nsid = idstr.rsplit('.', 1)
    except ValueError:
        if defaultnsgroup is _MARKER:
            nsgroup = config.PYRO_NS_DEFAULTGROUP
            nsgroup = defaultnsgroup
        nsid = idstr
    if nsgroup is not None and not nsgroup.startswith(':'):
        nsgroup = ':' + nsgroup
    return nsgroup, nsid

def host_and_port(hoststr):
    if not hoststr:
        return None, None
        hoststr, port = hoststr.split(':')
    except ValueError:
        port = None
        port = int(port)
    return hoststr, port

def _get_daemon(daemonhost, start=True):
    if not daemonhost in _DAEMONS:
        if not start:
            raise Exception('no daemon for %s' % daemonhost)
        if not _DAEMONS:
        host, port = host_and_port(daemonhost)
        daemon = core.Daemon(host=host, port=port)
        _DAEMONS[daemonhost] = daemon
    return _DAEMONS[daemonhost]

def locate_ns(nshost):
    """locate and return the pyro name server to the daemon"""
    return naming.NameServerLocator().getNS(*host_and_port(nshost))

def register_object(object, nsid, defaultnsgroup=_MARKER,
                    daemonhost=None, nshost=None, use_pyrons=True):
    """expose the object as a pyro object and register it in the name-server

    if use_pyrons is False, then the object is exposed, but no
    attempt to register it to a pyro nameserver is made.

    return the pyro daemon object
    nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
    daemon = _get_daemon(daemonhost)
    if use_pyrons:
        nsd = locate_ns(nshost)
        # make sure our namespace group exists
        except errors.NamingError:
    # use Delegation approach
    impl = core.ObjBase()
    qnsid = '%s.%s' % (nsgroup, nsid)
    uri = daemon.connect(impl, qnsid)
    _PYRO_OBJS[qnsid] = str(uri)'registered %s a pyro object using group %s and id %s',
                 object, nsgroup, nsid)
    return daemon

def get_object_uri(qnsid):
    return _PYRO_OBJS[qnsid]

def ns_unregister(nsid, defaultnsgroup=_MARKER, nshost=None):
    """unregister the object with the given nsid from the pyro name server"""
    nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
        nsd = locate_ns(nshost)
    except errors.PyroError, ex:
        # name server not responding
        _LOGGER.error('can\'t locate pyro name server: %s', ex)
            nsd.unregister('%s.%s' % (nsgroup, nsid))
  '%s unregistered from pyro name server', nsid)
        except errors.NamingError:
            _LOGGER.warning('%s not registered in pyro name server', nsid)

def ns_reregister(nsid, defaultnsgroup=_MARKER, nshost=None):
    """reregister a pyro object into the name server. You only have to specify
    the name-server id of the object (though you MUST have gone through
    `register_object` for the given object previously).

    This is especially useful for long running server while the name server may
    have been restarted, and its records lost.
    nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
    qnsid = '%s.%s' % (nsgroup, nsid)
    nsd = locate_ns(nshost)
    except errors.NamingError:
        # make sure our namespace group exists
        except errors.NamingError:
    nsd.register(qnsid, _PYRO_OBJS[qnsid])

def ns_get_proxy(nsid, defaultnsgroup=_MARKER, nshost=None):
    if nshost is None, the nameserver is found by a broadcast.
    # resolve the Pyro object
    nsgroup, nsid = ns_group_and_id(nsid, defaultnsgroup)
        nsd = locate_ns(nshost)
        pyrouri = nsd.resolve('%s.%s' % (nsgroup, nsid))
    except errors.ProtocolError, ex:
        raise errors.PyroError(
            'Could not connect to the Pyro name server (host: %s)' % nshost)
    except errors.NamingError:
        raise errors.PyroError(
            'Could not get proxy for %s (not registered in Pyro), '
            'you may have to restart your server-side application' % nsid)
    return core.getProxyForURI(pyrouri)

def get_proxy(pyro_uri):
    """get a proxy for the passed pyro uri without using a nameserver
    return core.getProxyForURI(pyro_uri)

def set_pyro_log_threshold(level):
    pyrologger = logging.getLogger('Pyro.%s' % str(id(util.Log)))
    # remove handlers so only the root handler is used
    pyrologger.handlers = []
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.