Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using RPyC and property decorator to set a value via a setter method on remote host #504

Open
CryptoMathician opened this issue Aug 3, 2022 · 4 comments
Assignees
Labels
Bug Confirmed bug Triage Investigation by a maintainer has started

Comments

@CryptoMathician
Copy link

Hi,

I want to use RPyC to access properties of a class from the remote host, but when I try to get it work only the getter is working correctly and the setter not. Here the details:

Server.py
import rpyc
from rpyc.utils.server import ThreadedServer


@rpyc.service
class MyService(rpyc.Service):
    def __init__(self):
        self._x = 10
        self._y = 2

    @property
    def x(self) -> int:
        return self._x

    @x.setter
    def x(self, v: int) -> None:
        self._x = v

    @property
    def y(self) -> int:
        return self._y

    @y.setter
    def y(self, v: int) -> None:
        self._y = v


def main():
    t = ThreadedServer(MyService, port=8000, protocol_config={
        "allow_all_attrs": True,
        "allow_setattr": True,
        "allow_delattr": True
    })
    print("Listening on port 8000...")
    t.start()


if __name__ == "__main__":
    main()
Client.py
import rpyc


def main():
    c = rpyc.connect("localhost", 8000)
    x = c.root.x
    print(f"x: {x}\ttype: {type(x)}")
    print(dir(c.root))
    c.root.x = 42


if __name__ == "__main__":
    main()

# Example: https://stackoverflow.com/questions/34844127/using-rpyc-to-update-properties-on-a-remote-object

The expected result is that I am able to set the property x of the remote object MyService.
However, I get a different result. This is the output of the "Client.py":

x: 10	type: <class 'int'>
['ALIASES', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_connect', '_protocol', '_rpyc_delattr', '_rpyc_setattr', '_x', '_y', 'exposed_get_service_aliases', 'exposed_get_service_name', 'get_service_aliases', 'get_service_name', 'on_connect', 'on_disconnect', 'x', 'y']
Traceback (most recent call last):
  File "<path>\Client.py", line 13, in <module>
    main()
  File "<path>\Client.py", line 9, in main
    c.root.x = 42
  File "<path>\venv\lib\site-packages\rpyc\core\netref.py", line 165, in __setattr__
    syncreq(self, consts.HANDLE_SETATTR, name, value)
  File "<path>\venv\lib\site-packages\rpyc\core\netref.py", line 63, in syncreq
    return conn.sync_request(handler, proxy, *args)
  File "<path>\venv\lib\site-packages\rpyc\core\protocol.py", line 490, in sync_request
    return _async_res.value
  File "<path>\venv\lib\site-packages\rpyc\core\async_.py", line 108, in value
    raise self._obj
_get_exception_class.<locals>.Derived: access denied

========= Remote Traceback (1) =========
Traceback (most recent call last):
  File "<path>\venv\lib\site-packages\rpyc\core\protocol.py", line 324, in _dispatch_request
    res = self._HANDLERS[handler](self, *args)
  File "<path>\venv\lib\site-packages\rpyc\core\protocol.py", line 631, in _handle_setattr
    return self._access_attr(obj, name, (value,), "_rpyc_setattr", "allow_setattr", setattr)
  File "<path>\venv\lib\site-packages\rpyc\core\protocol.py", line 553, in _access_attr
    return accessor(obj, name, *args)
  File "<path>\venv\lib\site-packages\rpyc\core\service.py", line 75, in _rpyc_setattr
    raise AttributeError("access denied")
AttributeError: access denied

I am using a virtual environment with the following pyvenv.cfg:

home = C:\Program Files\Python310
implementation = CPython
version_info = 3.10.4.final.0
virtualenv = 20.4.7
include-system-site-packages = false
base-prefix = C:\Program Files\Python310
base-exec-prefix = C:\Program Files\Python310
base-executable = C:\Program Files\Python310\python.exe

RPyC version: 5.2.1
Python Version: 3.10
Operatin System: Windows 10

To reproduce the error run the "Server.py" and then the "Client.py".

The documentation Link and Link didn't helped me.

I would appreciate you, when you are able to help.

@CryptoMathician
Copy link
Author

Maybe as an additional comment.
I don't want to use the magic methods to set the value.
It would be nice to have it work out of the box like it should work.

@comrumino
Copy link
Collaborator

comrumino commented Aug 4, 2022

Hm. Odd behavior. I'll have to dig in more when I have time. This behavior is not unique to the new decorators from what I can tell at first glance.

@comrumino comrumino self-assigned this Aug 4, 2022
@comrumino comrumino added Bug Confirmed bug Triage Investigation by a maintainer has started labels Aug 4, 2022
@CryptoMathician
Copy link
Author

Thank you! Let me know when I am able to help you regarding this topic.

@achrafka
Copy link

Because there is two methods in Service class _rpyc_delattr and _rpyc_setattr which they raise AttributeError i guess it's about security implications

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Confirmed bug Triage Investigation by a maintainer has started
Projects
None yet
Development

No branches or pull requests

3 participants