Autobahn|Python : Synchronous RPC ?

317 views
Skip to first unread message

Arnon Marcus

unread,
Apr 5, 2015, 8:04:02 AM4/5/15
to wam...@googlegroups.com
Hi, I was wondering how people are integrating/using AutobahnPython client, in their code.
All the examples have all the calls within a context of the OnJoin method in a component-class.
Is there a way to just have an object that exposes rpc in a synchronous/imperative style?
I see that in other client-implementations of WAMP you can do stuff like:
result = session.call('someMethod', someArgs, someKeywordArgs)

Is this possible with AutobahnPython?
If not, how then is it expected that people using it should embed rpc into an existing code-base?

I guess one can do something like:

session = ApplicationSession()

def call(procedure, *args, **kwargs):
    yield session.call(procedure, args, kwargs)

resault = call("com.mymethod").next()

Would that even work?
If so, is that advisable?

It is not clear from the documentation how Autobahn is expected to be used - it seems as thought there is an implicit-assumption that the reader understands that his/her entire code-base needs to exist inside the onJoin method of a component, or that there is where it should be initialized from - the moment the code gets to "runner.run(Component)" it starts waiting for asynchronous operations to occur within the context of the component - nowhere in the documentation is this being stated explicitly. Perhaps the documentation assumes a working-knowledge of using Twisted?! If so, then I think that at least THAT assumption should be stated explicitly somewhere..

Any thoughts?

Arnon Marcus

unread,
Apr 5, 2015, 8:17:58 AM4/5/15
to wam...@googlegroups.com
Say I have a PyQt tool I want to write.
Qt has it's own event-loop thing going on:

app = QtGui.QApplication()

The moment the code gets to some QWidget's ".show()" call, it enters the QApplication's event-loop.

How would one use a WAMP rpc session within a PyQt-based tool?
Is it even possible?

Is twisted able to work within such a context?
Or does it need to be 'in-charge' of the execution-context for any use-case?

Tobias Oberstein

unread,
Apr 9, 2015, 6:02:12 PM4/9/15
to wam...@googlegroups.com
Hi Arnon,

Am 05.04.2015 um 14:04 schrieb Arnon Marcus:
> Hi, I was wondering how people are integrating/using AutobahnPython
> client, in their code.
> All the examples have all the calls within a context of the OnJoin
> method in a component-class.
> Is there a way to just have an object that exposes rpc in a
> synchronous/imperative style?
> I see that in other client-implementations of WAMP you can do stuff like:
> |
> result =session.call('someMethod',someArgs,someKeywordArgs)

Yes:

http://autobahn.ws/python/wamp/programming.html#calling-procedures

The "yield" thing is using co-routines, looks "synchronous", but
actually runs asynch under the hood.

There is no way to use AutobahnPython in blocking code based apps -
because it blocks the event loop. (there are ways of running the
blocking code on a different thread though).

> |
>
> Is this possible with AutobahnPython?
> If not, how then is it expected that people using it should embed rpc
> into an existing code-base?

If the code base is blocking, that's a problem. Blocking code means, the
event loop stops, and things will stop working.

>
> I guess one can do something like:
>
> session = ApplicationSession()
>
> def call(procedure, *args, **kwargs):
> yield session.call(procedure, args, kwargs)
>
> resault = call("com.mymethod").next()

See the yield thing above ..

>
> Would that even work?
> If so, is that advisable?

Using yield is perfectly fine. It will make your code look synchronous,
but it is still running asynch (and you still must not block).

>
> It is not clear from the documentation how Autobahn is expected to be
> used - it seems as thought there is an implicit-assumption that the
> reader understands that his/her entire code-base needs to exist inside
> the onJoin method of a component, or that there is where it should be
> initialized from - the moment the code gets to "runner.run(Component)"
> it starts waiting for asynchronous operations to occur within the
> context of the component - nowhere in the documentation is this being
> stated explicitly. Perhaps the documentation assumes a working-knowledge
> of using Twisted?! If so, then I think that at least THAT assumption
> should be stated explicitly somewhere..

"Autobahn|Python is a WebSocket / WAMP library for Python 2 and 3 on
Twisted and asyncio"

is on the homepage http://autobahn.ws/

But yes, basic knowledge of either Twisted or asyncio is assumed.

Cheers,
/Tobias

PS: as this is Autobahn related (a specific WAMP implementation) the
post would better fit the Autobahn mailing list ..

>
> Any thoughts?
>
> --
> You received this message because you are subscribed to the Google
> Groups "WAMP" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to wampws+un...@googlegroups.com
> <mailto:wampws+un...@googlegroups.com>.
> To post to this group, send email to wam...@googlegroups.com
> <mailto:wam...@googlegroups.com>.
> Visit this group at http://groups.google.com/group/wampws.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/wampws/4585c86f-b79c-424d-853b-0d653d67d448%40googlegroups.com
> <https://groups.google.com/d/msgid/wampws/4585c86f-b79c-424d-853b-0d653d67d448%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Elvis Stansvik

unread,
Apr 15, 2015, 4:02:37 AM4/15/15
to wam...@googlegroups.com
On Sunday, April 5, 2015 at 2:17:58 PM UTC+2, Arnon Marcus wrote:
Say I have a PyQt tool I want to write.
Qt has it's own event-loop thing going on:

app = QtGui.QApplication()

The moment the code gets to some QWidget's ".show()" call, it enters the QApplication's event-loop.

How would one use a WAMP rpc session within a PyQt-based tool?
Is it even possible?

Since I've recently done a very small demo at work doing just this, I'll answer here (though Autobahn group would be better): You can use qtreactor [1], which is a Twisted reactor driven by the Qt 4 event loop.

I'm attaching the small demo I did at work, which shows a couple of RPC calls being made from a Qt 4 application. Note that it does not include the backend, so you'll have to imagine it. Try it out with

  $ python setup.py build_ui
  $ python setup.py develop
  $ lamp_controller

in a virtualenv. Also note that the reactor isn't shutting down properly when the Qt application exits, which leaves the program running even after the dialog has been closed. I believe this is an old bug in qtreactor which has bubbled up, and I'm tracking it here [2].

Cheers,
Elvis

lamp_controller.zip

Elvis Stansvik

unread,
Apr 15, 2015, 4:05:39 AM4/15/15
to wam...@googlegroups.com
On Wednesday, April 15, 2015 at 10:02:37 AM UTC+2, Elvis Stansvik wrote:
On Sunday, April 5, 2015 at 2:17:58 PM UTC+2, Arnon Marcus wrote:
Say I have a PyQt tool I want to write.
Qt has it's own event-loop thing going on:

app = QtGui.QApplication()

The moment the code gets to some QWidget's ".show()" call, it enters the QApplication's event-loop.

How would one use a WAMP rpc session within a PyQt-based tool?
Is it even possible?

Since I've recently done a very small demo at work doing just this, I'll answer here (though Autobahn group would be better): You can use qtreactor [1], which is a Twisted reactor driven by the Qt 4 event loop.

Sorry, think I got that backwards: It's a reactor that also drives the Qt event loop. Anyway, it's one or the other :)

Elvis
Reply all
Reply to author
Forward
0 new messages