15

This is a follow-up question to A list of available DBus services.

The following python code will list all available DBus services.

import dbus
for service in dbus.SystemBus().list_names():
    print(service)

How do we list out the object paths under the services in python? It is ok if the answer does not involve python although it is preferred.

I am using Ubuntu 14.04

  • It is ok if the answer does not involve python although it is preferred. – user768421 May 15 '15 at 6:09
13

As 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):

enter image description here


Sure, you can easily get the object paths via command line e.g. with gdbus:

gdbus introspect --system --dest org.freedesktop.UPower --object-path \
/org/freedesktop/UPower --recurse | awk '/^ *node /{print $2}'
/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

I don't have qdbus installed but according to this page

qdbus --system org.freedesktop.UPower

should produce a similar result.

  • How do I create a list of object paths from rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower') ? – Khurshid Alam Apr 28 '17 at 10:03
  • No, I mean creating a python list of object paths, so that I can check (in my script) if particular object-path exists in the list. It prints the objectpath alright., But I want something like k = rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower'). I suppose it is possible by modifying the function little bit. – Khurshid Alam Apr 28 '17 at 10:39
  • Example code with qbus: bus = dbus.SessionBus()..... obj_path = '/org/gnome/Gnote/RemoteControl'.......... cmd = 'qdbus org.gnome.Gnote'......... while obj_path not in ((subprocess.check_output(cmd, shell=True)).decode("utf-8")).split("\n"): ........pass – Khurshid Alam Apr 28 '17 at 10:41
  • @KhurshidAlam - initialize a list before the function e.g. mylist=[] then replace print with mylist.append and then as the last command in that function block return mylist - that's pretty much what there is... you can then iterate over the list or whatever e.g. add at the bottom of the script for x in mylist: print("OBJ_PATH", x) to have them printed with a OBJ_PATH prefix... – don_crissti Apr 28 '17 at 13:32
3

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.

enter image description here

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).

1

What I know from my experience to get the object paths of a bus name (service) it is possible to introspect with object path '/' i.e. (using the above example)

introspectfunc('org.freedesktop.UPower', '/') 

this should return:

<node name="/"> 
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/></node>

then introspect with path '/org'

introspectfunc('org.freedesktop.UPower', '/org')

this should return:

<node name="/org"> 
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/></node>

and so on:

introspectfunc('org.freedesktop.UPower', '/org/freedesktop')
introspectfunc('org.freedesktop.UPower', '/org/freedesktop/UPower')
etc.

It is like going through the folder structure of the hard drive where the object path '/' is the root and every node is subfolder. This seems the best way to retrieve the object paths of a particular bus name (service) and to construct a collection containing the object paths

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.