From 96711524cff8898372b4f5bab255c82875dc1850 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 23 Jul 2014 22:14:24 +0200 Subject: [PATCH] docs on @expose added. Fixes #45 --- MANIFEST.in | 4 ++ docs/source/clientcode.rst | 47 +++++++------------ docs/source/servercode.rst | 85 ++++++++++++++++++++++++++++++++-- tests/PyroTests/test_server.py | 4 +- 4 files changed, 103 insertions(+), 37 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 90b3af2a..0eb22e6c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -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__ diff --git a/docs/source/clientcode.rst b/docs/source/clientcode.rst index d1a69777..8b259b9f 100644 --- a/docs/source/clientcode.rst +++ b/docs/source/clientcode.rst @@ -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 ============ @@ -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 diff --git a/docs/source/servercode.rst b/docs/source/servercode.rst index a13b190b..d58edacd 100644 --- a/docs/source/servercode.rst +++ b/docs/source/servercode.rst @@ -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 diff --git a/tests/PyroTests/test_server.py b/tests/PyroTests/test_server.py index da370444..fb2a761b 100644 --- a/tests/PyroTests/test_server.py +++ b/tests/PyroTests/test_server.py @@ -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): @@ -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