Deprecated: Function call_user_method() is deprecated in /var/hostings/98tau0417/dfwpython.org/pmwiki/cookbook/beautifier/php/Beautifier/Core.php on line 564

Deprecated: Function call_user_method() is deprecated in /var/hostings/98tau0417/dfwpython.org/pmwiki/cookbook/beautifier/php/Beautifier/Core.php on line 564

Deprecated: Function call_user_method() is deprecated in /var/hostings/98tau0417/dfwpython.org/pmwiki/cookbook/beautifier/php/Beautifier/Core.php on line 564

Deprecated: Function call_user_method() is deprecated in /var/hostings/98tau0417/dfwpython.org/pmwiki/cookbook/beautifier/php/Beautifier/Core.php on line 564
The Dallas Ft. Worth Pythoneers | DBusProgramming / HomePage
SearchWiki:
  6 User(s) Active on Site
  233 Wiki Pages

Most Recently Modified

Club Resources (edit)

How This Wiki Works

Meeting space complements of:
Computer books
            and technical books at discount prices
Check them out; they are a great source of technical books at very good prices!

If you have shopped at Nerdbooks.com, help them out by reviewing them at ResellerRatings.com. You will need your invoice number to prove you are a real customer, and not just ballot stuffing.
Recent Changes Printable View Page History Edit Page
Content Last Modified on October 16, 2005, at 03:28 AM CST

Riding the D-BUS Using Python

Project Source Repository


What is it?

D-BUS(approve sites) is a message bus system for Linux, a simple way for applications to talk to one another. It is part of the Free Desktop Project(approve sites) and is being built into many Linux distributions.

In my case, I wanted to write Python programs that are aware of devices being plugged/unplugged, of the hardware configuration of my laptop. I wanted to be able to intercept button pushes for various special items on the laptop.


How is it structured?

There are (at least) two software buses present by default, one for system-wide communication (perhaps between users), and one desktop-wide communication, within a single user's desktop environment.

Buses are created by the first application to connect to a unique name. In this case the system bus is initially created by a system daemon (for events such as "new hardware device added" or "printer queue changed") and the user bus by a per-user-login-session daemon (for general IPC needs among user applications).

To see these daemons running, use "ps axf" and look for processes like:

  /usr/bin/dbus-daemon-1 --system
  /usr/bin/dbus-daemon-1 --session

Some Linux distributions may not start both of these, in which case you won't have those buses available to you.

The message bus is built on top of a general one-to-one message passing framework, which can be used by any two apps to communicate directly (without going through the message bus daemon).

The underlying protocol only supports one-to-one connections but by relying upon a bus daemon who sits in the center, he can forward messages to other interested parties, making the bus behave as a one-to-many. There is one such daemon per bus so in our case, a system bus daemon and a user bus daemon.

Unlike network sockets, over the bus is sent messages, not byte streams. A message consists of a header identifying the kind of message, and a body containing a data payload.


How do I use it from within Python?

There isn't much tutorial material for using D-BUS, hence these wiki pages. However you can read the D-BUS Python source and learn a bit. You'll find it under your Python library, in my case /usr/lib/python2.4/site-packages/dbus/dbus.py.

To connect to the system-wide bus,

  import dbus
  bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)

Or to connect to the user's desktop-wide session bus,

  import dbus
  bus = dbus.Bus(dbus.Bus.TYPE_SESSION)

How do I talk over this bus, say to the Bus Daemon?

The entities residing on the bus are called "services" and are represented by other processes or applications connected to the bus. One of those processes is of course the bus daemon himself.

To locate a service you must know its name. Services are named using a 'dotted-name' symbol, similar to Python modules, Java namespaces and so forth. The name of the bus daemon is "org.freedesktop.DBus".

  dbus_service = bus.get_service("org.freedesktop.DBus")

A service consists of a collection of objects on which we can invoke methods. You do not talk with the service, you talk with the service's objects. Each service documents the name of their objects. In the case of the bus daemon, its standard object is "/org/freedesktop/DBus". Note the slashes and not periods, which were used for the name of the service.

The object /org/freedesktop/DBus implements the org.freedesktop.DBus interface. Don't worry about the details of interfaces here.

  dbus_object = dbus_service.get_object("/org/freedesktop/DBus", "org.freedesktop.DBus")

Now we can invoke methods of the bus daemon and it will seamlessly be communicated between processes and such for us by the D-BUS infrastructure.

One of those methods is ListServices(), which returns a list of all the other services registered on this bus. Let's put it all together and discover what else is running on our bus.

  import dbus
  bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
  dbus_service = bus.get_service("org.freedesktop.DBus")
  dbus_object = dbus_service.get_object("/org/freedesktop/DBus", "org.freedesktop.DBus")
  print dbus_object.ListServices()

Try it again but use TYPE_SESSION instead of TYPE_SYSTEM. Since they are different buses they will have different services.

Note: If your Linux distribution doesn't run the user session bus daemon, attempts to access the session bus will fail. If so, read about how to set it up using the command "man dbus-launch".


With whom else can I communicate over these buses?

Broadcast Service

There appears to be a service named "org.freedesktop.Broadcast" for sending to everyone on the bus. I don't see proof of its existence yet.

Talking to the Print Spooler

I haven't found any proof this exists as of yet.

Talking to the HardwareManager

The reason I started this document was so I could listen to hardware-related events on my laptop.

The name of the hardware abstraction layer daemon is "org.freedesktop.Hal".

  hal_service = bus.get_service("org.freedesktop.Hal")

File: /etc/X11/xinit/xinitrc.d/30dbus-launch.sh

#!/bin/sh
<:vspace>
eval `dbus-launch --sh-syntax --exit-with-session`
export DBUS_SESSION_BUS_ADDRESS
export DBUS_SESSION_BUS_PID
Recent Changes Printable View Page History Edit Page