1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
Blocking quick start
+++++++++++++++++++++
.. py:currentmodule:: sdbus
Interface classes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Python-sdbus works by declaring interface classes.
Interface classes for blocking IO should be derived from :py:class:`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
:py:func:`dbus_method` and :py:func:`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 :ref:`blocking-vs-async`
Initiating proxy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:py:meth:`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 :py:func:`dbus_method` decorator.
If the remote object sends an error reply an exception with base of :py:exc:`.DbusFailedError`
will be raised. See :doc:`/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 :py:func:`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 :py:func:`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 :py:exc:`.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)
|