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 DICTprops);
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()