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)