# Python Programming/Dbus

In Linux, **Dbus** is a way for processes to communicate with each
other. For example, programs like
Pidgin instant
messenger allow other programs to find out or change the user\'s status
(Available, Away, etc). Another example is the
network-manager service
that publishes which internet connection is active. Programs that
sometimes connect to the internet can then pick the best time to
download updates to the system.

## Buses

Messages are sent along buses. Services attach themselves to these
buses, and allow clients to pass messages to and from them.

There are two main buses, the **system bus** and **session bus**.
Services on the system bus affect the whole system, such as providing
information about the network or disk drives. Services on the session
bus provide access to programs running on the desktop, like Pidgin.

``` python
import dbus

sys_bus = dbus.SystemBus()
```

## Objects and interfaces

Services attached to a bus can be contacted using their **well-known
name**. While this could be any string, the format is normally that of a
reverse domain name: an example for a spreadsheet program called
\"CalcProgram\" from \"My Corp Inc.\" could be
\"com.mycorp.CalcProgram\".

Services publish objects using slash-separated paths (this is similar to
webpages). Someone on dbus can request an object if they know this path.

The object passed back is not a full object: it just refers to the
service\'s copy of the object. It is called a **proxy object**.

``` python
proxy_for_cell_a2 = sys_bus.get_object('com.mycorp.CalcProgram', '/spreadsheet1/cells/a2')
```

Before the proxy object can be used, we need to specify what type of
object it is. We do this by creating an interface object.

``` python
cell_a2 = dbus.Interface(proxy_for_cell_a2, 'com.mycorp.CalcProgram.SpreadsheetCell')
```

Whatever methods are set up for this type of object can be called:

``` python
cell_a2.getContents()
```

  Name                      Example                                  Description
  ------------------------- ---------------------------------------- ---------------------------------------------
  service well known name   com.mycorp.CalcProgram                   Identifies the application
  path of an object         /spreadsheet1/cells/a2                   Identifies an object published by a service
  interface                 com.mycorp.CalcProgram.SpreadsheetCell   Identifies what type of object we expect

## dbus-python examples

These examples have been tested with dbus-python 0.83.0. Older library
versions may not have the same interface.

Calling an interface\'s methods / Listing HAL Devices:

``` python
import dbus

bus = dbus.SystemBus()
hal_manager_object = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
hal_manager_interface = dbus.Interface(hal_manager_object, 'org.freedesktop.Hal.Manager')

# calling method upon interface
print hal_manager_interface.GetAllDevices()

# accessing a method through 'get_dbus_method' through proxy object by specifying interface
method = hal_manager_object.get_dbus_method('GetAllDevices', 'org.freedesktop.Hal.Manager')
print(method())

# calling method upon proxy object by specifying the interface to use
print( hal_manager_object.GetAllDevices(dbus_interface='org.freedesktop.Hal.Manager'))
```

Introspecting an object:

``` python
import dbus

bus = dbus.SystemBus()
hal_manager_object = bus.get_object(
    'org.freedesktop.Hal',          # service
    '/org/freedesktop/Hal/Manager'  # published object
)

introspection_interface = dbus.Interface(
    hal_manager_object,
    dbus.INTROSPECTABLE_IFACE,
)

# Introspectable interfaces define a property 'Introspect' that
# will return an XML string that describes the object's interface
interface = introspection_interface.Introspect()
print(interface)
```

Avahi:

``` python
import dbus

sys_bus = dbus.SystemBus()

# get an object called / in org.freedesktop.Avahi to talk to
raw_server = sys_bus.get_object('org.freedesktop.Avahi', '/')

# objects support interfaces. get the org.freedesktop.Avahi.Server interface to our org.freedesktop.Avahi object.
server = dbus.Interface(raw_server, 'org.freedesktop.Avahi.Server')

# The so-called documentation is at /usr/share/avahi/introspection/Server.introspect
print(server)
print(server.GetVersionString())
print(server.GetHostName())
```

## pydbus examples

These examples have been tested with pydbus 0.2 and 0.3.

Calling an interface\'s methods / Listing systemd units:

``` python
from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get(
    '.systemd1' # service name - names starting with . automatically get org.freedesktop prepended.
    # no object path - it'll be set to the service name transformed to the path format (/org/freedesktop/systemd1)
)

for unit in systemd.ListUnits()[0]:
    print(unit)
```

Introspecting an object:

``` python
from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get('.systemd1')

# Introspectable interfaces define a property 'Introspect' that
# will return an XML string that describes the object's interface
print(systemd.Introspect()[0])

# Introspection data is automatically converted to Python's help system data
help(systemd)
```

Avahi:

``` python
from pydbus import SystemBus

bus = SystemBus()

# get an object called / in org.freedesktop.Avahi to talk to
avahi = bus.get('.Avahi', '/')

# See the object's API
help(avahi)

print(avahi.GetVersionString())
print(avahi.GetHostName())
```

## References

-   dbus-python
    tutorial,
    dbus.freedesktop.org, Simon McVittie, 2006-06-14
-   pydbus
    README.rst,
    github.com
-   DbusExamples,
    wiki.python.org
-   D-Bus Howto,
    developer.pidgin.im
-   Rough notes: Python and
    D-Bus,
    archived version, A.M. Kuchling, 2007, originally at www.amk.ca

