Re: D-Bus Versus Varlink
Lawrence D'Oliveiro <ldo-kC51rjc0cqs1dNLGKZg6taU/[email protected]> Mon, 25 Mar 2024 15:18:01 +1300
| Newsgroups | gmane.comp.freedesktop.dbus |
|---|---|
| Organization | Geek Central |
| Message-ID | <[email protected]> |
OK, here is my initial stab <https://gitlab.com/ldo/darlink>, <https://bitbucket.org/ldo17/darlink> at a pure-Python wrapper for implementing the Varlink protocol. Those familiar with DBussy, my Python wrapper for libdbus, will see some similarities and some differences. Some similarities: * Support for asyncio (the standard event loop API with async/await). This should be pretty much mandatory in anything networky being done in Python these days. * This library, too, is split into two modules, one handling the lower-level interface (direct construction/manipulation/sending/reception of messages) and the other at a higher level (supporting Python interface classes that wrap around protocol interface definitions). * An “Interface” hierarchy of Python classes for representing interface definitions and the components thereof: protocol types, method definitions etc. Functions are provided to easily convert between the protocol introspection format and the Python object format. * The use of class decorators and method decorators to attach interface information to interface class definitions and their method definitions, for use by the high-level request-dispatch mechanism and also the built-in introspection handler. * A function for constructing proxy-interface classes, so that protocol method calls can be made directly as method calls on the Python proxy objects. * An interface class provided as standard that you can attach to higher-level connection objects, that will automatically provide the introspection function for all interface classes (including itself) that you register for handling requests on that connection. Some differences: * Separate connection classes for sync versus async connections (at the lower level; the higher level only supports async connections), with all the same method calls, but potentially blocking ones are async in the latter. The constructor for ConnectionAsync objects is also async, so you have to await the result of the instantiation. I think this makes more sense than the technique I used in DBussy of explicitly getting the current event loop and attaching it to a Connection to enable async operation; that makes use of calls which the Python folks seem to be deprecating nowadays. * Varlink allows for custom enum types and custom names for struct types, so I support this in the higher-level interface as well: put an “@enumtype” decorator on a Python enumeration class, and it will attach the necessary information to add a corresponding Varlink enumeration to the interface definition, with automatic conversions both ways. Use the “structtype” function to generate a struct class whose constructor just returns a dict that is limited to the right field names. Some of the differences represent lessons learned from creating DBussy. For example, to avoid writing (nearly) the same code twice, I came up with a technique for generating both sync and async versions of a class from common code.