D-Bus Versus Varlink
Lawrence D'Oliveiro
ldo at geek-central.gen.nz
Mon Mar 25 02:18:01 UTC 2024
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.
More information about the dbus
mailing list