RPyC – inherit from exposed class

Question:

I have an RpyC server that imports a specific module, a class inside this module should be exposed so that this class can then be inherited from the client side.

For testing purposes I removed the module importing/exposing and created a simple class inside my RPyC service called exposed_TestClass.

server side: rpyc_server.py

import rpyc
from rpyc.utils.server import ThreadedServer

class MyService(rpyc.Service):
    class exposed_TestClass:
        def exposed_Exec(self):
            print("original print of class")

t = ThreadedServer(MyService, port=12345)
t.start()

client side: python3 shell

>>> import rpyc
>>> conn = rpyc.connect("localhost", 12345)
>>> conn.root.TestClass
<class 'exposed_TestClass'>
>>> conn.root.TestClass()
<exposed_TestClass object at 0x7f2dda642588>
>>> #calling the Exec function also works, prints at server side
>>> conn.root.TestClass().Exec()
>>>
>>>
>>> # test inheriting class
>>> class MyClass(conn.root.TestClass):
...     def NewMethod(self):
...         print("printing from new method")
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/rpyc/core/netref.py", line 220, in method
    return syncreq(_self, consts.HANDLE_CALLATTR, name, args, kwargs)
  File "/usr/lib/python3/dist-packages/rpyc/core/netref.py", line 74, in syncreq
    conn = object.__getattribute__(proxy, "____conn__")
AttributeError: 'str' object has no attribute '____conn__'
Asked By: ColrblindMartian

||

Answers:

As per the documentation on: https://rpyc.readthedocs.io/en/latest/tutorial/tut2.html

Voila, netrefs (network references, also known as transparent object proxies) are special objects that delegate everything done on them locally to the corresponding remote objects. Netrefs may not be real lists of functions or modules, but they “do their best” to look and feel like the objects they point to… in fact, they even fool python’s introspection mechanisms!

on the client side, if you do:

import rpyc
conn = rpyc.connect("localhost", 12345)

o=conn.root.TestClass()
type_o = type(o)
print(type_o)

it will print out:

<netref class 'rpyc.core.netref.__main__.exposed_TestClass'>

So when trying to do:

class MyClass(type_o):
    def NewMethod(self):
        print("printing from new method")

You inherit from the proxy class definition but not from the remote class definition. So when documentation states

they “do their best”

, i think it exclude the possibility of doing inheritance from a remote class. I’ll be more than glad if ever someone can find a way to met your requirment.

Please note I made my tests by setting up the server using the following line:

t = ThreadedServer(MyService, port=12345, protocol_config={ 'allow_all_attrs': True })
Answered By: François Fournier

Server.py

import rpyc

from rpyc.utils.server import ThreadedServer


class ServerService(rpyc.Service):
    def exposed_bar(self, func):
        return func() + "Server said: Client get back this sentence"

print('starting server')
server = ThreadedServer(ServerService, port=18811)
server.start()

client.py

import rpyc
class ClientService(rpyc.Service):
    def exposed_foo(self):
        return "foo_exposed"

def foofunc():
    return "Client give this sentencen"

conn = rpyc.connect("192.168.72.3", 18811, service=ClientService)
print("Connection Success {}n".format(conn))
print(conn.root.bar(foofunc))
Answered By: ben othman zied
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.