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

Port to txaio? #35

Open
bochecha opened this issue May 29, 2016 · 7 comments
Open

Port to txaio? #35

bochecha opened this issue May 29, 2016 · 7 comments

Comments

@bochecha
Copy link
Contributor

Note: opening a new issue to avoid polluting the other one, which is about Python 3 after all.

Over at #11 (comment), you mentioned you'd be interested in having txdbus work with both twisted and asyncio.

How about porting txdbus to txaio?

That would achieve compatibility with asyncio and twisted.

@cocagne
Copy link
Owner

cocagne commented May 31, 2016

Thanks for the suggestion. I hadn't come across txaio yet and it' certainly
worth considering. The prevalence of Deferreds in the txdbus code base
means it'd probably require porting one module at a time over to the new
API but I don't see any significant barriers in the way. It'd be a
relatively straight-forward, if somewhat time-consuming, task.

If you're up to the challenge, I'd happily accept patches on a
txaio-specific branch and would be willing to convert the mainline over to
the txaio version once all of the unit tests are passing. At the moment I
have another side-project that is consuming almost all of my available free
time so I probably won't be able to contribute too much code but I'm sure I
can find time for a few reviews & merges. Hell, show you're a good
developer and I'll add you to the commit list for that matter :)

Thanks for the patch :)

Tom

On Sun, May 29, 2016 at 4:01 PM, Mathieu Bridon [email protected]
wrote:

Note: opening a new issue to avoid polluting the other one, which is about
Python 3 after all.

Over at #11 (comment)
#11 (comment), you
mentioned you'd be interested in having txdbus work with both twisted and
asyncio.

How about porting txdbus to txaio https://github.com/crossbario/txaio?

That would achieve compatibility with asyncio and twisted.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#35, or mute the thread
https://github.com/notifications/unsubscribe/ABrLfAge8WnPxtrT31WBVDaR-hLwaOQFks5qGf7AgaJpZM4IpYPz
.

@oberstet
Copy link

oberstet commented Jun 5, 2017

Co-author of txaio here;)

Using txaio, the txdbus library could be made working on Python 2.7+ for both Twisted and asyncio from one codebase.

txdbus in its implementation would need to stick to:

  1. no co-routines, only plain Deferreds/Futures (eg txaio.create_future() will produce either a Twisted Deferred or an asyncio Future depending on which framework was chosen using txaio.use_twisted() or txaio.use_asyncio())
  2. no use of Deferred chaining (as asyncio Futures don't support that in the way Twisted does)

Further, an internal protocol/factory abstraction is needed. Eg here is AutobahnPython, biggest txaio user:

  • autobahn.websocket.protocol.WebSocketClientProtocol contains all network framework independent code
  • then there are 2 classes: autobahn.twisted.websocket.WebSocketClientProtocol and autobahn.asyncio.websocket.WebSocketClientProtocol which have the network framework specific code
  • these classes are the ones used by users, and they derive from 2 classes: WebSocketAdapterProtocol and the generic WebSocketClientProtocol
  • the adapter class member function WebSocketAdapterProtocol.dataReceived (Twisted) or WebSocketAdapterProtocol.data_received (asyncio) then forward that to the generic WebSocketClientProtocol._dataReceived method

Granted, this is a bit of a tricky design, but it achieves the goal of minimizing network framework specific code, maximize agnostic code, and all from a single code base.

Also important to note: while the above approach puts some burden on the library implementor, the users of the library have maximum freedom and convenience.

Eg it is no problem using the latest Python 3.6 co-routine goodies in app code on top of the library - the resulting app won't run on both Twisted/asyncio then of course, because the app code writer decided. Of course the app code itself could also be written without co-routines/chaining, and then it would run on both (eg allowing to switch framework from a command line option) - but I wouldn't recommend that for apps (only for libs).


The code base seems to be mostly Python 3 compatible, which is great of course:

===============================================================================
[SKIPPED]
Not yet ported to python3

txdbus.test.test_authentication.ServerObjectTester.test_bad_command
txdbus.test.test_authentication.ServerObjectTester.test_bad_mech
txdbus.test.test_authentication.ServerObjectTester.test_bad_mech2
txdbus.test.test_authentication.ServerObjectTester.test_cancel
txdbus.test.test_authentication.ServerObjectTester.test_max_rejects
txdbus.test.test_authentication.ServerObjectTester.test_no_null_byte_at_start
txdbus.test.test_authentication.ServerObjectTester.test_reject
txdbus.test.test_authentication.ServerObjectTester.test_retry
txdbus.test.test_authentication.ServerObjectTester.test_too_long
-------------------------------------------------------------------------------
Ran 255 tests in 1.768s

PASSED (skips=9, successes=246)
(cpy361_7) oberstet@thinkpad-t430s:~/scm/3rdparty/txdbus$ 

@DurandA
Copy link

DurandA commented Jun 12, 2017

In the meantime, you can use txdbus within an asyncio app using asyncioreactor and asFuture(loop) which are now merged in trunk:

import asyncio
from asyncio.tasks import ensure_future
from twisted.internet import asyncioreactor

loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
asyncioreactor.install(eventloop=loop)

from txdbus import error, client

async def show_desktop_notification():
    '''
    Displays "Hello World!" in a desktop notification window for 3 seconds
    '''
    con = await client.connect(reactor, 'session').asFuture(loop)

    notifier = await con.getRemoteObject('org.freedesktop.Notifications',
                                         '/org/freedesktop/Notifications').asFuture(loop)

    nid = await notifier.callRemote('Notify',
                                    'Example Application',
                                    0,
                                    '',
                                    'Tx DBus Example',
                                    'Hello World!',
                                    [], dict(),
                                    3000).asFuture(loop)

ensure_future(show_desktop_notification())
loop.run_forever()

@DurandA
Copy link

DurandA commented Jun 13, 2017

You can also use txdbus as usual (with Deferred objects) within an asyncio loop:

import asyncio
from asyncio.tasks import ensure_future
from twisted.internet import asyncioreactor

loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
asyncioreactor.install(eventloop=loop)

from twisted.internet import reactor, defer, task
from txdbus import error, client

@defer.inlineCallbacks
def show_desktop_notification():
    '''
    Displays "Hello World!" in a desktop notification window for 3 seconds
    '''
    con = yield client.connect(reactor, 'session')

    notifier = yield con.getRemoteObject('org.freedesktop.Notifications',
                                         '/org/freedesktop/Notifications')

    nid = yield notifier.callRemote('Notify',
                                    'Example Application',
                                    0,
                                    '',
                                    'Tx DBus Example',
                                    'Hello World!',
                                    [], dict(),
                                    3000)

reactor.callWhenRunning(show_desktop_notification)
reactor.startRunning()
loop.run_forever()

@exvito
Copy link
Collaborator

exvito commented Jun 13, 2017

@DurandA shared a few examples that are possible due to recent Twisted developments, allowing Twisted code to interoperate with asyncio code and vice-versa.

Maybe the docs could include an "asyncio" integration section with these two examples and a link to Twisted's docs about it?

@WhyNotHugo
Copy link
Collaborator

WhyNotHugo commented Jun 15, 2017

Would you like to create a PR with these examples in the README? 🙂

@ntninja
Copy link

ntninja commented Jun 24, 2017

Just so you know, I just stumbled over this (I guess somewhat experimental) pure-python dbus client implementation that claims to have support for blocking, asyncio & Tornado I/O1 by utilizing an I/O-free core2:
https://gitlab.com/takluyver/jeepney

It also has an high-level interface that is slightly more low-level that what txdbus offers1:

import asyncio

from jeepney import DBusAddress, new_method_call
from jeepney.integrate.asyncio import connect_and_authenticate

notifications = DBusAddress('/org/freedesktop/Notifications',
                            bus_name='org.freedesktop.Notifications',
                            interface='org.freedesktop.Notifications')

async def send_notification():
    (transport, protocol) = await connect_and_authenticate(bus='SESSION')

    msg = new_method_call(notifications, 'Notify', 'susssasa{sv}i',
                            ('jeepney_test',  # App name
                             0,     # Not replacing any previous notification
                             '',    # Icon
                             'Hello, world!',  # Summary
                             'This is an example notification from Jeepney',
                             [], {},  # Actions, hints
                             -1,      # expire_timeout (-1 = default)
                            ))
    # Send the message and await the reply
    reply = await protocol.send_message(msg)
    print('Notification ID:', reply[0])

loop = asyncio.get_event_loop()
loop.run_until_complete(send_notification())

Building something like pydbus's API on top this could indeed be a viable alternative?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants