Translate

Archives

Retrieving a Property using Python and GDbus

The documentation on retrieving or setting an D-Bus object’s properties using Python is pityful and mostly inaccurate. Recently GDBus has replaced dbus-glib as the preferred way to interface with D-Bus on GNOME platforms.

The central concepts of D-Bus are modelled in a very similar way in dbus-glib and GDBus. Both have objects representing connections, proxies and method invocations. However there are some important differences:

  • dbus-glib uses the D-Bus libdbus reference implementation, GDBus does not. Instead, it relies on GIO streams as transport layer, and has its own implementation for the the D-Bus connection setup and authentication.
  • dbus-glib uses the GObject type system for method arguments and return values, including a homegrown container specialization mechanism. GDBus relies on the GVariant type system which is explicitly designed to match D-Bus types.
  • dbus-glib models only D-Bus interfaces and does not provide any types for objects. GDBus models both D-Bus interfaces (via the GDBusInterface, GDBusProxy and GDBusInterfaceSkeleton types) and objects (via the GDBusObject, GDBusObjectSkeleton and GDBusObjectProxy types).
  • GDBus includes native support for the org.freedesktop.DBus.Properties (via the GDBusProxy type) and org.freedesktop.DBus.ObjectManager D-Bus interfaces, dbus-glib does not.

Many native APIs support object properties or attributes. These can be exposed via the org.freedesktop.DBus.Properties interface.

org.freedesktop.DBus.Properties.Get (in STRING interface_name,
                                     in STRING property_name,
                                     out VARIANT value);
org.freedesktop.DBus.Properties.Set (in STRING interface_name,
                                     in STRING property_name,
                                     in VARIANT value);
org.freedesktop.DBus.Properties.GetAll (in STRING interface_name,
                                        out DICT props);

The available properties and whether they are writable can be determined by calling org.freedesktop.DBus.Introspectable.Introspect.

The following is a simple example on how to get a property. The example is based on the Cinnamon 1.2 D-Bus interface. The available properties can be retrieved from the command line in a numbers of ways, dbus-send,gdbus, etc.

$ gdbus introspect --session --dest org.Cinnamon --object-path /org/Cinnamon --only-properties
node /org/Cinnamon {
  interface org.Cinnamon {
    properties:
      readwrite b OverviewActive = false;
      readonly i ApiVersion = 1;
      readonly s CinnamonVersion = '1.2.0';
  };
};

$ ./get_cinnamon_version
Cinnamon Version: 1.2.0
$


iHere is the source code for get_cinnamon_version which retrieves the readonly CinnamonVersion property:

#!/usr/bin/python

try:
    import os
    import sys
    import argparse
except ImportError, detail:
    print detail
    sys.exit(1)

from gi.repository import Gio, GLib


class Cinnamon:
    def __init__(self):
        try:
            self.bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
            self.proxy = Gio.DBusProxy.new_sync( self.bus, Gio.DBusProxyFlags.NONE, None,
                              'org.Cinnamon', '/org/Cinnamon', 'org.freedesktop.DBus.Properties', None)
        except:
            print "Exception: %s" % sys.exec_info()[1]

    def get_cinnamon_version(self):
        output = self.proxy.Get('(ss)', 'org.Cinnamon', 'CinnamonVersion')
        return output

def main():
    s = Cinnamon()
    version = s.get_cinnamon_version()
    print 'Cinnamon Version: %s' % (version)
    sys.exit(0)

if __name__ == "__main__":
    main()

Comments are closed.