I'm a bit confused with working with remote third-party libraries:
1) For example, I have server code:
import Pyro4
import Pyro4.naming
import Pyro4.utils.flame
Pyro4.config.REQUIRE_EXPOSE = False
Pyro4.config.FLAME_ENABLED = True
Pyro4.config.SERIALIZERS_ACCEPTED = set(["pickle"])
Pyro4.config.SERIALIZER = 'pickle' # for flameserver
def _main():
"""Start RPC server."""
ip_address = Pyro4.socketutil.getIpAddress(None, workaround127=True)
ns_daemon = Pyro4.naming.NameServerDaemon(host=ip_address, port=RPC_PORT)
Pyro4.utils.flame.start(ns_daemon)
from remote_management.rpc.component.shell import Shell
shell_uri = ns_daemon.register(Shell())
ns_daemon.nameserver.register("shell", shell_uri)
from remote_management.rpc.component.cpu import CPU
cpu_uri = ns_daemon.register(CPU())
ns_daemon.nameserver.register("cpu", cpu_uri)
ns_daemon.requestLoop()
ns_daemon.close()
if __name__ == "__main__":
_main()
The CPU component is like this:
import psutil
class CPU(object):
def ps(self):
return psutil.cpu_times()
When I use it in client like this:
import Pyro4
import Pyro4.utils.flame
import Pyro4.errors
Pyro4.config.SERIALIZER = "pickle"
proxy = Pyro4.Proxy("PYRONAME:cpu@myhost:47976")
print proxy.ps()
I get an error:
Traceback (most recent call last):
File "t.py", line 145, in <module>
print proxy.ps()
File "/home/korolev/.envs/auto/lib/python2.7/site-packages/Pyro4/core.py", line 187, in __call__
return self.__send(self.__name, args, kwargs)
File "/home/korolev/.envs/auto/lib/python2.7/site-packages/Pyro4/core.py", line 464, in _pyroInvoke
data = serializer.deserializeData(msg.data, compressed=msg.flags & message.FLAGS_COMPRESSED)
File "/home/korolev/.envs/auto/lib/python2.7/site-packages/Pyro4/util.py", line 170, in deserializeData
return self.loads(data)
File "/home/korolev/.envs/auto/lib/python2.7/site-packages/Pyro4/util.py", line 451, in loads
return pickle.loads(data)
ImportError: No module named psutil._pslinux
As you see it cannot be deserialized. And if I change return to:
return tuple(psutil.cpu_times())
, then it works.
2) I think this next problem has the same nature: The server code is almost the same except component
from remote_management.rpc.component.registrator import ModuleRegistrator
reg_uri = ns_daemon.register(ModuleRegistrator())
ns_daemon.nameserver.register("module_registrator", reg_uri)
If I need remote module, but don't have it locally, why I can't do just like this:
Registrator component:
class ModuleRegistrator(object):
def register(self, module):
module = importlib.import_module(module)
self._pyroDaemon.register(module)
return module
so when I use it in client:
proxy = Pyro4.Proxy("PYRONAME:module_registrator@myhost:47976")
print proxy.register("psutil").cpu_times()
I get an error:
Traceback (most recent call last):
File "t.py", line 145, in <module>
print proxy.register('psutil').cpu_times()
File "/home/korolev/.envs/auto/lib/python2.7/site-packages/Pyro4/core.py", line 279, in __getattr__
raise AttributeError("remote object '%s' has no exposed attribute or method '%s'" % (self._pyroUri, name))
AttributeError: remote object 'PYRONAME:module_registrator@myhost:47976' has no exposed attribute or method 'register'
Please help me understand this errors and where I'm missing something? And what is the best approach to handle things like this when working with third-party remotely? Thanks in advance!