Translate

Image of RHCE Red Hat Certified Engineer Linux Study Guide (Exam RH302) (Certification Press)
Image of Linux Kernel Development (3rd Edition)
Image of XSLT 2.0 and XPath 2.0 Programmer's Reference (Programmer to Programmer)
Image of Operating System Concepts

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.