How to list all object paths under a dbus service?
QT
setups provide the most convenient way to do it, via qdbus
:
qdbus --system org.freedesktop.UPower
prints
/
/org
/org/freedesktop
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/line_power_ADP0
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
As to the python way... per the official docs (under standard interfaces):
There are some standard interfaces that may be useful across various D-Bus applications.
org.freedesktop.DBus.Introspectable
This interface has one method:
org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
Objects instances may implement
Introspect
which returns an XML description of the object, including its interfaces (with signals and methods), objects below it in the object path tree, and its properties.
So here's a very simplistic example that should get you started. It uses xml.etree.ElementTree
and dbus
:
#!/usr/bin/env python
import dbus
from xml.etree import ElementTree
def rec_intro(bus, service, object_path):
print(object_path)
obj = bus.get_object(service, object_path)
iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
xml_string = iface.Introspect()
for child in ElementTree.fromstring(xml_string):
if child.tag == 'node':
if object_path == '/':
object_path = ''
new_path = '/'.join((object_path, child.attrib['name']))
rec_intro(bus, service, new_path)
bus = dbus.SystemBus()
rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')
It recursively introspects org.freedesktop.UPower
starting from e.g. /org/freedesktop/UPower
and prints all object paths (node names):
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/line_power_ADP0
which is pretty much what you'd get if you used d-feet
(not that you'd need it):
I am not sure you can do this programmatically in Python. You might but it will be a huge headache to figure out how. I tried to do it before and ended up hating Dbus. Anyhow I recommend to use d-feet if you want to investigate things. Below is a screenshot that I stole from my blog.
Once you know the program name, object path, etc. you can then use Python to access those things.
Example
progname = 'org.freedesktop.NetworkManager'
objpath = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'
bus = dbus.SystemBus()
obj = bus.get_object(progname, objpath) # Here we get object
intf = dbus.Interface(obj, intfname) # Here we get interface
meth = inf.get_dbus_method(methname) # Here we get method
meth() # And finally calling the method
As you see, it's a pain in the ass to get a simple thing done. But this is the easiest workflow you can get with Dbus!
So use a GUI tool to find out the object paths, interfaces, etc. Then use the code snippet above as a template to access those things. Also I suggest you do this via IPython's interpreter to see what methods, properties, etc. each object has (by hitting tab).
If the service has an object implementing org.freedesktop.DBus.ObjectManager
, its method GetManagedObjects
returns “all objects, interfaces and properties in a single method call.” For example, UDisks2 has such an object.