I am trying to understand how nameko works for basic RPC. I am looking to define microservices in separate files and being able to run them from command shell. With this structure service2 is not being able to invoke service1's RPC method. What is missing to get this working?
I have the following file structure:
-rwxrwxr-x 1 user user 240 Dec 15 01:49 nameko.sh* -rw-rw-r-- 1 user user 251 Dec 15 01:46 service1.py -rw-rw-r-- 1 user user 305 Dec 15 01:47 service2.py
Content of files are:
$ cat nameko.sh #!/bin/bash /usr/local/bin/nameko run service1:Microservice1 & nameko_id=$! echo 'Microservice 1 PID: ' $nameko_id /usr/local/bin/nameko run service2:Microservice2 & nameko_id=$! echo 'Microservice 2 PID: ' $nameko_id wait 2> /dev/null $ cat service1.py # -*- coding: utf-8 -*- from nameko.rpc import rpc, RpcProxy class Microservice1(object): name = "microservice1" @rpc def hello(self): print 'Microservice1 hello method invoked' return True $ cat service2.py # -*- coding: utf-8 -*- from nameko.rpc import rpc, RpcProxy class Microservice2(object): name = "microservice2" microservice1 = RpcProxy('microservice1') microservice1.hello() @rpc def hello(self): print 'Microservice2 hello method invoked' return True
And I am not being able to understand how to invoke hello method in Microservice 1 from Microservice 2:
$ ./nameko.sh Microservice 1 PID: 14782 Microservice 2 PID: 14783 Traceback (most recent call last): File "/usr/local/bin/nameko", line 11, in <module> sys.exit(main()) File "/usr/local/lib/python2.7/dist-packages/nameko/cli/main.py", line 66, in main args.main(args) File "/usr/local/lib/python2.7/dist-packages/nameko/cli/commands.py", line 85, in main starting services: microservice1 main(args) File "/usr/local/lib/python2.7/dist-packages/nameko/cli/run.py", line 179, in main import_service(path) File "/usr/local/lib/python2.7/dist-packages/nameko/cli/run.py", line 46, in import_service __import__(module_name) File "./service2.py", line 5, in <module> class Microservice2(object): File "./service2.py", line 11, in Microservice2 microservice1.hello() AttributeError: 'RpcProxy' object has no attribute 'hello' Connected to amqp://guest:**@127.0.0.1:5672//
But invoking nameko shell and running rpc method from microservice1 works:
Broker: pyamqp://guest:guest@localhost >>> n.rpc.microservice1.hello() True
Added information
Following Matt's answer I have edited service2.py as follows:
# -*- coding: utf-8 -*- from nameko.rpc import rpc, RpcProxy class Microservice2(object): name = "microservice2" @rpc def toctoc(self): print 'Microservice2 called hello method from Microservice1' m1 = RpcProxy('microservice1') m1.hello() return True
Now both services run, But still does not work, when I run a namejo shell and invoke toctoc method from Microservice2:
$ nameko shell Nameko Python 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] shell on linux2 Broker: pyamqp://guest:guest@localhost >>> n.rpc.microservice2.toctoc() Traceback (most recent call last): File "<console>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/nameko/rpc.py", line 374, in __call__ return reply.result() File "/usr/local/lib/python2.7/dist-packages/nameko/rpc.py", line 332, in result raise deserialize(error) RemoteError: AttributeError 'RpcProxy' object has no attribute 'hello' >>>
Last working code
With the help provided in the answers, a working version of this would be (in case it clarifies/helps others):
$ cat nameko.sh #!/bin/bash /usr/local/bin/nameko run service1:Microservice1 & nameko_id=$! echo 'Microservice 1 PID: ' $nameko_id /usr/local/bin/nameko run service2:Microservice2 & nameko_id=$! echo 'Microservice 2 PID: ' $nameko_id wait 2> /dev/null $ cat service1.py # -*- coding: utf-8 -*- from nameko.rpc import rpc, RpcProxy class Microservice1(object): name = "microservice1" @rpc def hello(self): print 'Microservice1 hello method invoked' return True $ cat service2.py # -*- coding: utf-8 -*- from nameko.rpc import rpc, RpcProxy class Microservice2(object): name = "microservice2" microservice1 = RpcProxy('microservice1') @rpc def remote_hello(self): print 'Microservice2 invokes hello method from Microservice1' self.microservice1.hello() return True