irmen / Pyro5

Pyro 5 - Python remote objects
https://pyro5.readthedocs.io
MIT License
305 stars 36 forks source link

Autoproxy by class #7

Closed Evidlo closed 5 years ago

Evidlo commented 5 years ago

I'm trying to use PyKeePass remotely to keep a password database open in a background process for a few minutes.

Here are my server and client:

import Pyro5.api
from pykeepass import PyKeePass as PyKeePassRemote

PyKeePass = Pyro5.api.expose(PyKeePassRemote)

@Pyro5.api.expose
class Factory(object):
    def PyKeePass(self, filename, password=None, keyfile=None):
        kp = PyKeePass(filename, password=password, keyfile=keyfile)
        self._pyroDaemon.register(kp)
        return kp

daemon = Pyro5.api.Daemon.serveSimple(
    {
        Factory: 'Factory'
    },
    host='localhost',
    port=9999,
    ns=False,
)
import Pyro5.api
from lxml import etree

Factory = Pyro5.api.Proxy('PYRO:Factory@localhost:9999')

kp = Factory.PyKeePass('test3.kdbx', 'password', 'test3.key')
kp.entries

Under the hood, kp.entries builds a list of Entry, Group, or Attachment objects.

However, I get TypeError: don't know how to serialize class <class 'lxml.etree._Element'> because Pyro tries to serialize these objects which contain some lxml _Element and _ElementTree objects.

In general, is there a way to tell Pyro5 to automatically pass objects of a certain type as remote objects rather than building adapters around every function in PyKeePass?

irmen commented 5 years ago

No, not in a general sense. Pyro only exposes objects via autoproxying if these objects are Pyro objects. So you'll have to do a little manual work (registering them with the daemon) before returning them. See the 'autoproxy' example and the documentation of this feature. Main reason is security and the principle to keep the remotely exposed interface explicit.