Blocking quick start

Interface classes

Python-sdbus works by declaring interface classes.

Interface classes for blocking IO should be derived from DbusInterfaceCommon.

The class constructor takes interface_name keyword to determine the D-Bus interface name for all D-Bus elements declared in the class body.

Example:

class ExampleInterface(DbusInterfaceCommon,
                       interface_name='org.example.myinterface'
                       ):
    ...

Interface class body should contain the definitions of methods and properties using the decorators dbus_method() and dbus_property() respectively.

Example:

from sdbus import (DbusInterfaceCommon,
                   dbus_method, dbus_property)


class ExampleInterface(DbusInterfaceCommon,
                       interface_name='org.example.myinterface'
                       ):
    # Method that takes an integer and does not return anything
    @dbus_method('u')
    def close_notification(self, an_int: int) -> None:
        raise NotImplementedError

    # Read only property of int
    @dbus_property()
    def test_int(self) -> int:
        raise NotImplementedError

This is an interface of that defines a one D-Bus method and one property.

The actual body of the decorated function will not be called. Instead the call will be routed through D-Bus to a another process. Interface can have non-decorated functions that will act as regular methods.

Blocking IO can only interact with existing D-Bus objects and can not be served for other processes to interact with. See Blocking vs Async

Initiating proxy

DbusInterfaceCommon.__init__() method takes service_name and object_path of the remote object that the object will proxy to.

Example creating a proxy and calling method:

...
# Initialize the object
d = ExampleInterface(
    service_name='org.example.test',
    object_path='/',
)

d.close_notification(1234)

Note

Successfully initiating a proxy object does NOT guarantee that the D-Bus object exists.

Methods

Methods are functions wrapped with dbus_method() decorator.

If the remote object sends an error reply an exception with base of DbusFailedError will be raised. See Exceptions for list of exceptions.

The wrapped function will not be called. Its recommended to set the function to raise NotImplementedError.

Example:

from sdbus import DbusInterfaceCommon, dbus_method


class ExampleInterface(...):

    ...
    # Body of some class

    @dbus_method('u')
    def close_notification(self, an_int: int) -> None:
        raise NotImplementedError

Properties

D-Bus property is defined by wrapping a function with dbus_property() decorator.

Example:

from sdbus import DbusInterfaceCommon, dbus_property

class ExampleInterface(...):

    ...
    # Body of some class

    # Property of str
    @dbus_property('s')
    def test_string(self) -> str:
        raise NotImplementedError

The new property behaves very similar to Pythons property() decorator.

# Initialize the proxy
d = ExampleInterface(
    service_name='org.example.test',
    object_path='/',
)

# Print it
print(d.test_string)

# Assign new string
d.test_string = 'some_string'

If property is read-only when DbusPropertyReadOnlyError will be raised.

Multiple interfaces

A D-Bus object can have multiple interfaces with different methods and properties.

To implement this define multiple interface classes and do a multiple inheritance on all interfaces the object has.

Example:

from sdbus import DbusInterfaceCommon, dbus_method


class ExampleInterface(DbusInterfaceCommon,
                       interface_name='org.example.myinterface'
                       ):

    @dbus_method('i')
    def example_method(self, an_int: int) -> None:
        raise NotImplementedError


class TestInterface(DbusInterfaceCommon,
                    interface_name='org.example.test'
                    ):

    @dbus_method('as')
    def test_method(self, str_array: List[str]) -> None:
        raise NotImplementedError


class MultipleInterfaces(TestInterface, ExampleInterface):
    ...

MultipleInterfaces class will have both test_method and example_method that will be proxied to correct interface names. (org.example.myinterface and org.example.test respectively)