dbus python help

Simon McVittie simon.mcvittie at collabora.co.uk
Tue Apr 1 05:02:55 PDT 2008


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thu, 27 Mar 2008 at 19:39:12 -0700, Praveen wrote (in private mail):
> I've been playing around with the dbus module for python (following
> your neat tuorial - thanks). However, I've hit a roadblock - I want to
> find all instances of a particular application running on my system
> (all of them register with the session bus). The scenario is some
> thing like this:
> 
> All instances implement the interface 'com.domain.API' and bind to the
> well known name '/com/domain', but each instance has a unique name
> (something like :1.34). So, I need to find how many instances of this
> application are connected to the bus.

The pattern we use in Telepathy is that Connection instances obtain
well-known names that cannot be activated (do not have a .service file)
but follow a predictable pattern,
org.freedesktop.Telepathy.Connection.<something>. The official way to
list Connection instances (as implemented by telepathy-glib) is to call
ListNames on the bus daemon, and look for names following that pattern.

A convenient way to make well-known names without collisions would be to
incorporate the unique name, so instance :1.34 obtains well-known name
com.domain.API.Instance.1.34 or something.

This would enable you to find instances without actually having to solve the
question you ask below - considerably more efficient that calling a
method on every app on the bus.

> for name in names:
>         print name
>         if name.startswith(':'):
>             try:
>                 proxy = remote_bus.get_object(name, '/com/domain')
>                 print proxy.get_dbus_method("Invoke",
> dbus_interface="com.domain.API")
>             except:
>                 print "exception:", sys.exc_info()[1]
>             else:
>                 print "%s is an instance" % name
> 
> ---------------------------------------------------------------------------
> 
> Obviously this code is wrong, because of the remote_bus.get_object()
> call in the for loop.

"Obviously"? Why is this wrong? If what you want is a proxy for the
object /com/domain (which may or may not actually exist) on the given
application (unique name), you're doing it right by calling
get_object().

If the definition of an instance of your API is
"the object at /com/domain implements com.domain.API" then this is
a reasonable thing to do.

> Long story short, given a unique name *only*,
> how do I get a proxy object and how do I know if it implements a
> particular interface (like com.domain.API) ?

The canonical way would be to call
org.freedesktop.DBus.Introspectable.Introspect and parse the XML;
however, if your interface has a method which always succeeds, or a property
which always exists, calling that method or the
org.freedesktop.DBus.Properties.GetAll method might be OK too.

In Telepathy, the Connection and Channel interfaces have a
GetInterfaces method which returns a list of additional interfaces
exported by the Connection or Channel (e.g. connections might support
renaming IM contacts, or not), and our newer interfaces have an
Interfaces property with the same semantics. You might find a similar
pattern useful, for extensible interface discovery without having to
parse XML.

    Simon
-----BEGIN PGP SIGNATURE-----

iD8DBQFH8iRvWSc8zVUw7HYRAvBkAKDU7VD2UsCGPcw1C94WyiKxdjtPmgCgwfxX
iLBQq0lAk+7GkNCOUsOyWME=
=+nU6
-----END PGP SIGNATURE-----


More information about the dbus mailing list