Skip to content
This repository has been archived by the owner on Jun 4, 2023. It is now read-only.

Commit

Permalink
docs on @expose added. Fixes #45
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Jul 23, 2014
1 parent 5ba99af commit 9671152
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 37 deletions.
4 changes: 4 additions & 0 deletions MANIFEST.in
Expand Up @@ -12,3 +12,7 @@ global-exclude *.pyc
global-exclude *.pyo
global-exclude *.coverage
global-exclude nosetests.xml
global-exclude .git
global-exclude .gitignore
global-exclude .tox
global-exclude __pycache__
47 changes: 16 additions & 31 deletions docs/source/clientcode.rst
Expand Up @@ -260,7 +260,10 @@ Here are some rules:
*Note:* you can still use the proxy object when it is disconnected: Pyro will reconnect it as soon as it's needed again.


.. index:: oneway call
.. index::
double: oneway; client method call

.. _oneway-calls-client:

Oneway calls
============
Expand All @@ -284,43 +287,25 @@ are more efficient because they immediately produce ``None`` as result and that'

.. index::
double: @Pyro4.oneway; client handling
double: decorator; oneway

**Specifying one-way methods using the @Pyro4.oneway decorator:**

You decide on the class of your Pyro object on the server, what methods are to be called as one-way.
You use the ``@Pyro4.oneway`` decorator on these methods to mark them for Pyro.
When the client proxy connects to the server it gets told automatically what methods are one-way,
you don't have to do anything on the client yourself. Any calls your client code makes on the proxy object
to methods that are marked with ``@Pyro4.oneway`` on the server, will happen as one-way calls::

import Pyro4

class PyroService(object):

def normal_method(self, args):
result = do_long_calculation(args)
return result

@Pyro4.oneway
def oneway_method(self, args):
result = do_long_calculation(args)
# no return value, cannot return anything to the client


See the :file:`oneway` example for more details.
**How to make methods one-way:**
You mark the methods of your class *in the server* as one-way by using a special *decorator*.
See :ref:`decorating-pyro-class` for details on how to do this.
See the :file:`oneway` example for some code that demonstrates the use of oneway methods.

.. index:: _pyroOneway
.. note::
There's another way of doing this, which was used in older Pyro versions. It is now deprecated
and support for it will be removed in the next Pyro version. It didn't use the metadata mechanism, but
instead you simply marked all the methods you want to call as one-way explicitly on the proxy yourself::

There's another way of telling Pyro what methods are one-way, which was used in older Pyro versions.
It is now deprecated and support for it will be removed in the next Pyro version. It didn't use the metadata mechanism, but
instead you simply marked all the methods you want to call as one-way explicitly on the proxy yourself.
You had to do this in every piece of client code that creates the proxy.
The :py:attr:`Pyro4.core.Proxy._pyroOneway` property on the proxy object is a set containing the names of the methods that
should be called as one-way (by default it is an empty set)::

proxy = Pyro4.Proxy(...)
proxy._pyroOneway.add("someMethod")
proxy._pyroOneway.update(["otherMethod", "processStuff"])

The :py:attr:`Pyro4.core.Proxy._pyroOneway` property is a set containing the names of the methods that
should be called as one-way (by default it is an empty set).


.. index:: batch calls
Expand Down
85 changes: 81 additions & 4 deletions docs/source/servercode.rst
Expand Up @@ -22,19 +22,96 @@ Make sure you are familiar with Pyro's :ref:`keyconcepts` before reading on.
single: decorators
single: @Pyro4.expose
single: @Pyro4.oneway
single: REQUIRE_EXPOSE
double: decorator; expose
double: decorator; oneway

.. _decorating-pyro-class:

Creating a Pyro class and using the Pyro4 decorators
====================================================
@todo: @expose on class

@todo: @expose on methods / properties
**What is exposed by default, and the REQUIRE_EXPOSE config item**

Pyro's default behavior is to expose *all* methods of your class
(unless they are private, which means the name is starting with a single or double underscore).
You don't have to do anything to your server side code to make it available to remote calls, apart from
registering the class with a Pyro daemon ofcourse.
This is for backward compatibility and ease-of-use reasons.

If you don't like this (maybe security reasons) or simply want to expose only a part of your class to the remote world,
you can tell Pyro to *require* the explicit use of the ``@expose`` decorator (described below) on the items that you want to make
available for remote access. If something doesn't have the decorator, it is not remotely accessible.
This behavior can be chosen by setting the ``REQUIRE_EXPOSE`` config item to ``True``. It is set to ``False`` by default.

**Exposing methods and attributes for remote access: the @expose decorator**

The ``@Pyro4.expose`` decorator is provided that lets you mark the following items to be available for remote access:

- classes (exposing a class has the effect of exposing every method and property of the class automatically)
- methods (including classmethod and staticmethod. You cannot expose a private method, i.e. name starting with underscore)
- properties (will be available as remote attributes on the proxy)

Remember that you must set the ``REQUIRE_EXPOSE`` config item to ``True`` to let all this have any effect!
Also because it is not possible to decorate attributes on a class, it is required to provide a @property for them
and decorate that with @exposed, if you want to provide a remotely accessible attribute.

Here's a piece of example code that shows how a partially exposed Pyro class may look like::

import Pyro4

Pyro4.config.REQUIRE_EXPOSE = True # make @expose do something

class PyroService(object):

value = 42 # not exposed

def __private__(self): # not exposed
pass

def _private(self): # not exposed
pass

@Pyro4.expose
def get_value(self): # exposed
return self.value

@Pyro4.expose
@property
def attr(self): # exposed as 'proxy.attr' remote attribute
return self.value

@Pyro4.expose
@attr.setter
def attr(self, value): # exposed as 'proxy.attr' writable
self.value = value



**Specifying one-way methods using the @Pyro4.oneway decorator:**

You decide on the class of your Pyro object on the server, what methods are to be called as one-way.
You use the ``@Pyro4.oneway`` decorator on these methods to mark them for Pyro.
When the client proxy connects to the server it gets told automatically what methods are one-way,
you don't have to do anything on the client yourself. Any calls your client code makes on the proxy object
to methods that are marked with ``@Pyro4.oneway`` on the server, will happen as one-way calls::

import Pyro4

class PyroService(object):

def normal_method(self, args):
result = do_long_calculation(args)
return result

@todo: @oneway
@Pyro4.oneway
def oneway_method(self, args):
result = do_long_calculation(args)
# no return value, cannot return anything to the client

@todo: explain REQUIRE_EXPOSE config item

See :ref:`oneway-calls-client` for the documentation about how client code handles this.
See the :file:`oneway` example for some code that demonstrates the use of oneway methods.


.. index:: publishing objects
Expand Down
4 changes: 2 additions & 2 deletions tests/PyroTests/test_server.py
Expand Up @@ -88,7 +88,7 @@ def getName(self):
return self.name

def unexposed(self):
return "you should not see this"
return "you should not see this" # .... only when REQUIRE_EXPOSE is set to True is this valid


class DaemonLoopThread(threadutil.Thread):
Expand Down Expand Up @@ -359,7 +359,7 @@ def testExposedNotRequired(self):
with self.daemon.proxyFor("unexposed") as p:
self.assertEqual(set(["unexposed", "getName"]), p._pyroMethods)
self.assertEqual("hello", p.getName())
self.assertEqual("you should not see this", p.unexposed())
self.assertEqual("you should not see this", p.unexposed()) # well, you should see it when REQUIRE_EXPOSE is False :)
finally:
Pyro4.config.REQUIRE_EXPOSE = old_require

Expand Down

0 comments on commit 9671152

Please sign in to comment.