---
name: "python-sdbus"
section: "1"
platform: "linux"
package: "python3-sdbus"
version: "0.14.0-1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/python-sdbus"
---

# python-sdbus(1)

python-sdbus Python-sdbus is the python D-Bus library that aim to use the modern features of python

## NAME

python-sdbus - python-sdbus

Python-sdbus is the python D-Bus library that aim to use the modern features of python

- •

  *Asyncio*

- •

  *Type hints*

- •

  *Based on fast sd-bus*

- •

  Unified client/server interface classes. Write interface class once.

- •

  D-Bus methods can have keyword and default arguments.

## D-BUS

D-Bus is the inter-process communication standard commonly used on Linux desktop.

This documentation expects you to be familiar with D-Bus concepts and conventions.

If you are unfamiliar with D-Bus you might want to read following pages:

*Wikipedia page*

*Lennart Poettering post about D-Bus*

*D-Bus specification by freedesktop.org*

*Install D-Spy D-Bus debugger and observe services and objects on your D-Bus*

### General Information

### Blocking vs Async

Python-sdbus supports both blocking and async IO.

Regular python functions are always blocking.

Asyncio is a part of python standard library that allows non-blocking io.

*Asyncio documentation*

Generally blocking IO should only be used for simple scripts and programs that interact with existing D-Bus objects.

### Blocking:

- •

  Blocking is easier to initiate (no event loop)

- •

  Properties behave exactly as Python properties do. (i.e. can assign with '=' operator)

- •

  Only allows one request at a time.

- •

  No D-Bus signals.

- •

  Cannot serve objects, only interact with existing object on D-Bus.

*Blocking quick start*

*Blocking API*

### Asyncio:

- •

  Calls need to be **await** ed.

- •

  Multiple requests at the same time.

- •

  Serve object on D-Bus for other programs.

- •

  D-Bus Signals.

*Asyncio quick start*

*Asyncio API*

### D-Bus types conversion

*D-Bus types reference*

**NOTE:**

Python integers are unlimited size but D-Bus integers are not. All integer types raise **OverflowError** if you try to pass number outside the type size.

Unsigned integers range is **0 \< (2\*\*bit\_size)-1**.

Signed integers range is **-(2\*\*(bit\_size-1)) \< (2\*\*(bit\_size-1))-1**.

| | | | |
| --- | --- | --- | --- |
| Name | D-Bus type | Python type | Description |
| Boolean | b | **bool** | **True** or **False** |
| Byte | y | **int** | Unsigned 8-bit integer. **Note:** array of bytes (*ay*) has different type in python domain. |
| Int16 | n | **int** | Signed 16-bit integer. |
| Uint16 | q | **int** | Unsigned 16-bit integer. |
| Int32 | i | **int** | Signed 32-bit integer. |
| Uint32 | u | **int** | Unsigned 32-bit integer. |
| Int64 | x | **int** | Signed 64-bit integer. |
| Uint64 | t | **int** | Unsigned 64-bit integer. |
| Double | d | **float** | Float point number |
| Unix FD | h | **int** | File descriptor |
| String | s | **str** | String |
| Object Path | o | **str** | Syntactically correct D-Bus object path |
| Signature | g | **str** | D-Bus type signature |
| Array | a | **list** | List of some single type. Example: **as** array of strings |
| Byte Array | ay | **bytes** | Array of bytes. Not a unique type in D-Bus but a different type in Python. Accepts both **bytes** and **bytearray**. Used for binary data. |
| Struct | () | **tuple** | Tuple. Example: **(isax)** tuple of int, string and array of int. |
| Dictionary | a{} | **dict** | Dictionary with key type and value type. **Note:** Dictionary is always a part of array. I.E. **a{si}** is the dict with string keys and integer values. **{si}** is NOT a valid signature. |
| Variant | v | **tuple** | Unknown type that can be any single type. In Python represented by a tuple of a signature string and a single type. Example: **("s", "test")** variant of a single string |

### Name conversions

D-Bus uses CamelCase for method names.

Python uses snake\_case.

When decorating a method name will be automatically translated from snake\_case to CamelCase. Example: **close\_notification** -\> **CloseNotification**

However, all decorators have a parameter to force D-Bus name to a specific value. See API documentation for a particular decorator.

### Default bus

Most object methods that take a bus as a parameter will use a thread-local default bus connection if a bus object is not explicitly passed.

Session bus is default bus when running as a user and system bus otherwise.

The *request\_default\_bus\_name\_async* and *request\_default\_bus\_name* can be used to acquire a service name on the default bus.

Use *sd\_bus\_open\_user()* and *sd\_bus\_open\_system()* to acquire a specific bus connection.

The *set\_default\_bus* can be used to set the new thread-local bus. This should be done before any objects that take bus as an init argument are created. If no bus has been set the new bus will be initialized and set as thread-local default.

The bus can also be set as default for the current context using *set\_context\_default\_bus*. The context refers to the standard library's **contextvars** module context variables frequently used in asyncio frameworks. Context-local default bus has higher priority over thread-local default bus.

### Glossary

- •

  **Bus** object representing connection to D-Bus.

- •

  - **Proxy** Python object that represents an object on D-Bus.

    Without proxy you manipulate messages directly.

- •

  **Remote** something that exists outside current Python process.

- •

  **Local** something that exists inside current Python scope.

- •

  - **Service Name** a well known name that an process can acquire on D-Bus.

    For example, systemd acquires **org.freedesktop.systemd1** name.

- •

  **Signature** D-Bus type definition. Represented by a string. See *D-Bus types conversion*.

### Contents

- •

  *Index*

- •

  *API Index*

- •

  *Search Page*

### Common API

These calls are shared between async and blocking API.

### Default bus

- **sdbus.default\_bus.get\_default\_bus() -\> SdBus**

  Get default bus.

  Returns context-local default bus if set or thread-local otherwise.

  If no default bus is set initializes a new bus using *sdbus.sd\_bus\_open()* and sets it as a thread-local default bus.

- **sdbus.default\_bus.set\_default\_bus(new\_default: SdBus) -\> None**

  Set thread-local default bus.

  Should be called before creating any objects that will use default bus.

  Default bus can be replaced but the change will only affect newly created objects.

- **sdbus.default\_bus.set\_context\_default\_bus(new\_default: SdBus) -\> Token\[SdBus\]**

  Set context-local default bus.

  Should be called before creating any objects that will use default bus.

  Default bus can be replaced but the change will only affect newly created objects.

  Context-local default bus has higher priority over thread-local one but has to be explicitly set.

  - **Returns**

    Token that can be used to reset context bus back. See **contextvars** documentation for details.

- **async sdbus.default\_bus.request\_default\_bus\_name\_async(new\_name: str, allow\_replacement: bool = False, replace\_existing: bool = False, queue: bool = False) -\> None**

  Asynchronously acquire a name on the default bus.

  - **Parameters**

    - •

      **new\_name** -- Name to acquire. Must be a valid D-Bus service name.

    - •

      **allow\_replacement** -- If name was acquired allow other D-Bus peers to take away the name.

    - •

      **replace\_existing** -- If current name owner allows, take away the name.

    - •

      **queue** -- Queue up for name acquisition. *SdBusRequestNameInQueueError* will be raised when successfully placed in queue. *Ownership* *change signal* should be monitored get notified when the name was acquired.

  - **Raises**

    *Name request exceptions* and other D-Bus exceptions.

- **sdbus.default\_bus.request\_default\_bus\_name(new\_name: str, allow\_replacement: bool = False, replace\_existing: bool = False, queue: bool = False) -\> None**

  Acquire a name on the default bus.

  Blocks until a reply is received from D-Bus daemon.

  - **Parameters**

    - •

      **new\_name** -- Name to acquire. Must be a valid D-Bus service name.

    - •

      **allow\_replacement** -- If name was acquired allow other D-Bus peers to take away the name.

    - •

      **replace\_existing** -- If current name owner allows, take away the name.

    - •

      **queue** -- Queue up for name acquisition. *SdBusRequestNameInQueueError* will be raised when successfully placed in queue. *Ownership* *change signal* should be monitored get notified when the name was acquired.

  - **Raises**

    *Name request exceptions* and other D-Bus exceptions.

### D-Bus connections calls

- **sdbus.sd\_bus\_open()**

  Opens a new bus connection. The session bus will be opened when available or system bus otherwise.

  - **Returns**

    Session or system bus.

  - **Return type**

    SdBus

- **sdbus.sd\_bus\_open\_user()**

  Opens a new user session bus connection.

  - **Returns**

    Session bus.

  - **Return type**

    SdBus

- **sdbus.sd\_bus\_open\_system()**

  Opens a new system bus connection.

  - **Returns**

    System bus.

  - **Return type**

    SdBus

- **sdbus.sd\_bus\_open\_system\_remote(host)**

  Opens a new system bus connection on a remote host through SSH. Host can be prefixed with **username@** and followed by **:port** and **/machine\_name** as in **systemd-nspawn** container name.

  - **Parameters**

    **host** (*str*) -- Host name to connect.

  - **Returns**

    Remote system bus.

  - **Return type**

    SdBus

- **sdbus.sd\_bus\_open\_system\_machine(machine)**

  Opens a new system bus connection in a systemd-nspawn container. Machine name can be prefixed with **username@**. Special machine name **.host** indicates local system.

  - **Parameters**

    **machine** (*str*) -- Machine (container) name.

  - **Returns**

    Remote system bus.

  - **Return type**

    SdBus

- **sdbus.sd\_bus\_open\_user\_machine(machine)**

  Opens a new user session bus connection in a systemd-nspawn container. Opens root user bus session or can be prefixed with **username@** for a specific user.

  - **Parameters**

    **machine** (*str*) -- Machine (container) name.

  - **Returns**

    Remote system bus.

  - **Return type**

    SdBus

### Helper functions

- **sdbus.encode\_object\_path(prefix, external)**

  Encode that arbitrary string as a valid object path prefixed with prefix.

  - **Parameters**

    - •

      **prefix** (*str*) -- Prefix path. Must be a valid object path.

    - •

      **external** (*str*) -- Arbitrary string to identify object.

  - **Returns**

    valid object path

  - **Return type**

    str

  Example on how systemd encodes unit names on D-Bus:

  ```
  from sdbus import encode_object_path
  # System uses /org/freedesktop/systemd1/unit as prefix of all units
  # dbus.service is a name of D-Bus unit but dot . is not a valid object path
  s = encode_object_path('/org/freedesktop/systemd1/unit', 'dbus.service')
  print(s)
  # Prints: /org/freedesktop/systemd1/unit/dbus_2eservice
  ```

- **sdbus.decode\_object\_path(prefix, full\_path)**

  Decode object name that was encoded with *encode\_object\_path()*.

  - **Parameters**

    - •

      **prefix** (*str*) -- Prefix path. Must be a valid object path.

    - •

      **full\_path** (*str*) -- Full path to be decoded.

  - **Returns**

    Arbitrary name

  - **Return type**

    str

  Example decoding systemd unit name:

  ```
  from sdbus import decode_object_path
  s = decode_object_path(
      '/org/freedesktop/systemd1/unit',
      '/org/freedesktop/systemd1/unit/dbus_2eservice'
  )
  print(s)
  # Prints: dbus.service
  ```

### Flags

Flags are **int** values that should be ORed to combine.

Example, *DbusDeprecatedFlag* plus *DbusHiddenFlag*: **DbusDeprecatedFlag \| DbusHiddenFlag**

- **sdbus.DbusDeprecatedFlag: int**

  Mark this method or property as deprecated in introspection data.

- **sdbus.DbusHiddenFlag: int**

  Method or property will not show up in introspection data.

- **sdbus.DbusUnprivilegedFlag: int**

  Mark this method or property as unprivileged. This means anyone can call it. Only works for system bus as user session bus is fully trusted by default.

- **sdbus.DbusNoReplyFlag: int**

  This method does not have a reply message. It instantly returns and does not have any errors.

- **sdbus.DbusPropertyConstFlag: int**

  Mark that this property does not change during object life time.

- **sdbus.DbusPropertyEmitsChangeFlag: int**

  This property emits signal when it changes.

- **sdbus.DbusPropertyEmitsInvalidationFlag: int**

  This property emits signal when it invalidates. (means the value changed but does not include new value in the signal)

- **sdbus.DbusPropertyExplicitFlag: int**

  This property is too heavy to calculate so its not included in GetAll method call.

- **sdbus.DbusSensitiveFlag: int**

  Data in messages in sensitive and will be scrubbed from memory after message is red.

### 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)

### Blocking API

### Classes

- **class sdbus.DbusInterfaceCommon(interface\_name)**

  D-Bus interface class. D-Bus methods and properties should be defined using *dbus\_property()* and *dbus\_method()* decorators.

  - **Parameters**

    **interface\_name** (*str*) -- Sets the D-Bus interface name that will be used for all properties and methods defined in the body of the class

  - **\_\_init\_\_(service\_name, object\_path\[, bus\])**

    Init will create a proxy to a remote object

    - **Parameters**

      - •

        **service\_name** (*str*) -- Remote object D-Bus connection name. For example, systemd uses **org.freedesktop.systemd1**

      - •

        **object\_path** (*str*) -- Remote object D-Bus path. Should be a forward slash separated path. Starting object is usually **/**. Example: **/org/freedesktop/systemd/unit/dbus\_2eservice**

      - •

        **bus** (*SdBus*) -- Optional D-Bus connection object. If not passed the default D-Bus will be used.

  - **dbus\_ping()**

    Pings the remote service using D-Bus.

    Useful to test if connection or remote service is alive.

    **WARNING:**

    This method is ignores the particular object path meaning it can NOT be used to test if object exist.

  - **dbus\_machine\_id()**

    Returns the machine UUID of D-Bus the object is connected to.

    - **Returns**

      machine UUID

    - **Return type**

      str

  - **dbus\_introspect()**

    Get D-Bus introspection XML.

    It is users responsibility to parse that data.

    - **Returns**

      string with introspection XML

    - **Return type**

      str

  - **properties\_get\_all\_dict()**

    Get all object properties as a dictionary where keys are member names and values are properties values.

    Equivalent to **GetAll** method of the **org.freedesktop.DBus.Properties** interface but the member names are automatically translated to python names. (internally calls it for each interface used in class definition)

    - **Parameters**

      **on\_unknown\_member** (*str*) -- If an unknown D-Bus property was encountered either raise an **"error"** (default), **"ignore"** the property or **"reuse"** the D-Bus name for the member.

    - **Returns**

      dictionary of properties

    - **Return type**

      dict\[str, Any\]

  Example:

  ```
  from sdbus import (DbusInterfaceCommon,
                     dbus_method, dbus_property)
  class ExampleInterface(DbusInterfaceCommon,
                         interface_name='org.example.my'
                         ):
      # Method that takes an integer and does not return anything
      @dbus_method('u')
      def close_notification(self, an_int: int) -> None:
          raise NotImplementedError
      # Method that does not take any arguments and returns a list of str
      @dbus_method()
      def get_capabilities(self) -> list[str]:
          raise NotImplementedError
      # Method that takes a dict of {str: str} and returns an int
      @dbus_method('a{ss}')
      def count_entries(self, a_dict: dict[str, str]) -> int:
          raise NotImplementedError
      # Read only property of int
      @dbus_property()
      def test_int(self) -> int:
          raise NotImplementedError
      # Read/Write property of str
      @dbus_property('s')
      def test_string(self) -> str:
          raise NotImplementedError
  ```

- **class sdbus.DbusObjectManagerInterface(interface\_name)**

  This class is almost identical to *DbusInterfaceCommon* but implements *ObjectManager* interface.

  - **get\_managed\_objects()**

    Get the objects this object manager in managing.

    - **Returns**

      Triple nested dictionary that contains all the objects paths with their properties values.

      dict\[ObjectPath, dict\[InterfaceName, dict\[PropertyName, PropertyValue\]\]\]

    - **Return type**

      dict\[str, dict\[str, dict\[str, Any\]\]\]

### Decorators

- **@sdbus.dbus\_method(\[input\_signature\[, flags\[, method\_name\]\]\])**

  Define D-Bus method

  Decorated function becomes linked to D-Bus method. Always use round brackets () even when not passing any arguments.

  - **Parameters**

    - •

      **input\_signature** (*str*) -- D-Bus input signature. Defaults to "" meaning method takes no arguments. Required if method takes any arguments.

    - •

      **flags** (*int*) --

      modifies behavior. No effect on remote connections. Defaults to 0 meaning no special behavior.

      See *Flags* .

    - •

      **method\_name** (*str*) -- Explicitly define remote method name. Usually not required as remote method name will be constructed based on original method name.

  Defining methods example:

  ```
  from sdbus import DbusInterfaceCommon, dbus_method
  class ExampleInterface(DbusInterfaceCommon,
                         interface_name='org.example.my'
                         ):
      # Method that takes an integer and does not return anything
      @dbus_method('u')
      def close_notification(self, an_int: int) -> None:
          raise NotImplementedError
      # Method that does not take any arguments and returns a list of str
      @dbus_method()
      def get_capabilities(self) -> list[str]:
          raise NotImplementedError
      # Method that takes a dict of {str: str} and returns an int
      @dbus_method('a{ss}')
      def count_entries(self, a_dict: dict[str, str]) -> int:
          raise NotImplementedError
  ```

  Calling methods example:

  ```
  # Initialize the object
  d = ExampleInterface(
      service_name='org.example.test',
      object_path='/',
  )
  d.close_notification(1234)
  l = d.get_capabilities()
  d.count_entries({'a': 'asdasdasd', 'b': 'hgterghead213d'})
  ```

- **@sdbus.dbus\_property(\[property\_signature\[, flags\[, property\_name\]\]\])**

  Define D-Bus property

  Property works just like @property decorator would. Always use round brackets () even when not passing any arguments.

  Read only property can be indicated by passing empty D-Bus signature "".

  Trying to assign a read only property will raise **AttributeError**

  - **Parameters**

    - •

      **property\_signature** (*str*) -- D-Bus property signature. Empty signature "" indicates read-only property. Defaults to empty signature "". Required only for writable properties.

    - •

      **flags** (*int*) --

      modifies behavior. No effect on remote connections. Defaults to 0 meaning no special behavior.

      See *Flags* .

    - •

      **property\_name** (*str*) -- Explicitly define remote property name. Usually not required as remote property name will be constructed based on original method name.

  Defining properties example:

  ```
  from sdbus import DbusInterfaceCommon, dbus_property
  class ExampleInterface(DbusInterfaceCommon,
                         interface_name='org.example.myproperty'
                         ):
      # Property of int
      @dbus_property('i')
      def test_int(self) -> int:
          raise NotImplementedError
      # Property of str
      @dbus_property('s')
      def test_string(self) -> str:
          raise NotImplementedError
  ```

  Properties usage example:

  ```
  # Initialize the object
  d = ExampleInterface(
      service_name='org.example.test',
      object_path='/',
  )
  # Print the int
  print(d.test_int)
  # Assign new string
  d.test_string = 'some_string'
  # Print it
  print(d.test_string)
  ```

- •

  *Index*

- •

  *Module Index*

- •

  *Search Page*

### Asyncio quick start

### Interface classes

Python-sdbus works by declaring interface classes.

Interface classes for async IO should be derived from *DbusInterfaceCommonAsync*.

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:

```
from sdbus import DbusInterfaceCommonAsync
class ExampleInterface(DbusInterfaceCommonAsync,
                       interface_name='org.example.myinterface'
                       ):
    ...
```

Interface class body should contain the definitions of methods, properties and signals using decorators such as *dbus\_method\_async()*, *dbus\_property\_async()* and *dbus\_signal\_async()*.

Example:

```
from sdbus import (DbusInterfaceCommonAsync, dbus_method_async,
                   dbus_property_async, dbus_signal_async)
class ExampleInterface(DbusInterfaceCommonAsync,
                       interface_name='org.example.myinterface'
                       ):
    # Method that takes an integer and multiplies it by 2
    @dbus_method_async('i', 'i')
    async def double_int(self, an_int: int) -> None:
        return an_int * 2
    # Read only property of str
    @dbus_property_async('s')
    def read_string(self) -> int:
        return 'Test'
    # Signal with a list of strings
    @dbus_signal_async('as')
    def str_signal(self) -> list[str]:
        raise NotImplementedError
```

### Initiating proxy

*DbusInterfaceCommonAsync* provides two methods for proxying remote objects.

*DbusInterfaceCommonAsync.new\_proxy()* class method bypasses the class **\_\_init\_\_** and returns proxy object.

*DbusInterfaceCommonAsync.\_proxify()* should be used inside the **\_\_init\_\_** methods if your class is a proxy only.

Recommended to create proxy classes that a subclass of the interface:

```
from sdbus import DbusInterfaceCommonAsync
class ExampleInterface(...):
    # Some interface class
    ...
class ExampleClient(ExampleInterface):
    def __init__(self) -> None:
        # Your client init can proxy to any object based on passed arguments.
        self._proxify('org.example.test', '/')
```

**NOTE:**

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

### Serving objects

*DbusInterfaceCommonAsync.export\_to\_dbus()* method will export the object to the D-Bus. After calling it the object becomes visible on D-Bus for other processes to call.

Example using ExampleInterface from before:

```
from sdbus import request_default_bus_name_async
loop = get_event_loop()
i = ExampleInterface()
async def start() -> None:
    # Acquire a name on the bus
    await request_default_bus_name_async('org.example.test')
    # Start serving at / path
    i.export_to_dbus('/')
loop.run_until_complete(start())
loop.run_forever()
```

### Connection transparency

The interface objects are designed to be transparent to their connection status. This means if the object not proxied to remote the calls to decorated methods will still work in the local scope.

This is the call to local object:

```
i = ExampleInterface()
async def test() -> None:
    print(await i.double_int(5))  # Will print 10
```

This is a call to remote object at **'org.example.test'** service name and **'/'** path:

```
i = ExampleInterface.new_proxy('org.example.test', '/')
async def test() -> None:
    print(await i.double_int(5))  # Will print 10
```

### Methods

Methods are async function calls wrapped with *dbus\_method\_async()* decorator. (see the API reference for decorator parameters)

Methods have to be async function, otherwise **AssertionError** will be raised.

While method calls are async there is a inherit timeout timer for any method call.

To return an error to caller you need to raise exception which has a *DbusFailedError* as base. Regular exceptions will not propagate.

See *Exceptions*.

Example:

```
from sdbus import DbusInterfaceCommonAsync, dbus_method_async
class ExampleInterface(...):
    ...
    # Body of some class
    # Method that takes a string
    # and returns uppercase of that string
    @dbus_method_async(
        input_signature='s',
        result_signature='s',
        result_args_names=('uppercased', )  # This is optional but
                                            # makes arguments have names in
                                            # introspection data.
    )
    async def upper(self, str_to_up: str) -> str:
        return str_to_up.upper()
```

Methods behave exact same way as Python methods would:

```
print(await example_object.upper('test'))  # prints TEST
```

### Properties

Properties are a single value that can be read and write.

To declare a read only property you need to decorate a regular function with *dbus\_property\_async()* decorator.

Example:

```
from sdbus import DbusInterfaceCommonAsync, dbus_property_async
class ExampleInterface(...):
    ...
    # Body of some class
    # Read only property. No setter defined.
    @dbus_property_async('i')
    def read_only_number(self) -> int:
        return 10
```

To create a read/write property you need to decorate the setter function with the **setter** attribute of your getter function.

Example:

```
from sdbus import DbusInterfaceCommonAsync, dbus_property_async
class ExampleInterface(...):
    ...
    # Body of some class
    # Read/write property. First define getter.
    @dbus_property_async('s')
    def read_write_str(self) -> str:
        return self.s
    # Now create setter. Method name does not matter.
    @read_write_str.setter  # Use the property setter method as decorator
    def read_write_str_setter(self, new_str: str) -> None:
        self.s = new_str
```

Properties are supposed to be lightweight. Make sure you don't block event loop with getter or setter.

Async properties do not behave the same way as **property()** decorator does.

To get the value of the property you can either directly **await** on property or use **get\_async()** method. (also need to be awaited)

To set property use **set\_async()** method.

Example:

```
...
# Somewhere in async function
# Assume we have example_object of class defined above
print(await example_object.read_write_str)  # Print the value of read_write_str
...
# Set read_write_str to new value
await example_object.read_write_str.set_async('test')
```

### Signals

To define a D-Bus signal wrap a function with *dbus\_signal\_async()* decorator.

The function is only used for type hints information. It is recommended to just put **raise NotImplementedError** in to the body of the function.

Example:

```
from sdbus import DbusInterfaceCommonAsync, dbus_signal_async
class ExampleInterface(...):
        ...
        # Body of some class
        @dbus_signal_async('s')
        def name_changed(self) -> str:
            raise NotImplementedError
```

To catch a signal use **async for** loop:

```
async for x in example_object.name_changed:
    print(x)
```

**WARNING:**

If you are creating an asyncio task to listen on signals make sure to bind it to a variable and keep it referenced otherwise garbage collector will destroy your task.

A signal can be emitted with *emit* method.

Example:

```
example_object.name_changed.emit('test')
```

Signals can also be caught from multiple D-Bus objects using *catch\_anywhere* method. The async iterator will yield the path of the object that emitted the signal and the signal data.

*catch\_anywhere* can be called from class but in such case the service name must be provided.

Example:

```
async for path, x in ExampleInterface.name_changed.catch_anywhere('org.example.test'):
    print(f"On {path} caught: {x}")
```

### Subclass Overrides

If you define a subclass which overrides a declared D-Bus method or property you need to use *dbus\_method\_async\_override()* and *dbus\_property\_async\_override()* decorators. Overridden property can decorate a new setter.

Overridden methods should take same number and type of arguments.

Example:

```
from sdbus import (dbus_method_async_override,
                   dbus_property_async_override)
# Some subclass
class SubclassInterface(...):
    ...
    @dbus_method_async_override()
    async def upper(self, str_to_up: str) -> str:
        return 'Upper: ' + str_to_up.upper()
    @dbus_property_async_override()
    def str_prop(self) -> str:
        return 'Test property' + self.s
    # Setter needs to be decorated again to override
    @str_prop.setter
    def str_prop_setter(self, new_s: str) -> None:
        self.s = new_s.upper()
```

### 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 DbusInterfaceCommonAsync
class ExampleInterface(DbusInterfaceCommonAsync,
                       interface_name='org.example.myinterface'
                       ):
    @dbus_method_async('i', 'i')
    async def double_int(self, an_int: int) -> None:
        return an_int * 2
class TestInterface(DbusInterfaceCommonAsync,
                    interface_name='org.example.test'
                    ):
    @dbus_method_async('as', 's')
    async def join_str(self, str_array: list[str]) -> str:
        return ''.join(str_array)
class MultipleInterfaces(TestInterface, ExampleInterface):
    ...
```

**MultipleInterfaces** class will have both **test\_method** and **example\_method** that will be wired to correct interface names. (**org.example.myinterface** and **org.example.test** respectively)

### Asyncio API

### Classes

- **class sdbus.DbusInterfaceCommonAsync(interface\_name)**

  D-Bus async interface class. D-Bus methods and properties should be defined using *dbus\_property\_async()*, *dbus\_signal\_async()*, and *dbus\_method\_async()* decorators.

  **NOTE:**

  Don't forget to call **super().\_\_init\_\_()** in derived classes init calls as it sets up important attributes.

  - **Parameters**

    - •

      **interface\_name** (*str*) -- Sets the D-Bus interface name that will be used for all properties, methods and signals defined in the body of the class.

    - •

      **serving\_enabled** (*bool*) -- If set to **True** the interface will not be served on D-Bus. Mostly used for interfaces that sd-bus already provides such as **org.freedesktop.DBus.Peer**.

  - **async dbus\_ping()**

    Pings the remote service using D-Bus.

    Useful to test if connection or remote service is alive.

    **WARNING:**

    This method is ignores the particular object path meaning it can NOT be used to test if object exist.

  - **async dbus\_machine\_id()**

    Returns the machine UUID of D-Bus the object is connected to.

    - **Returns**

      machine UUID

    - **Return type**

      str

  - **async dbus\_introspect()**

    Get D-Bus introspection XML.

    It is users responsibility to parse that data.

    - **Returns**

      string with introspection XML

    - **Return type**

      str

  - **async properties\_get\_all\_dict()**

    Get all object properties as a dictionary where keys are member names and values are properties values.

    Equivalent to **GetAll** method of the **org.freedesktop.DBus.Properties** interface but the member names are automatically translated to python names. (internally calls it for each interface used in class definition)

    - **Parameters**

      **on\_unknown\_member** (*str*) -- If an unknown D-Bus property was encountered either raise an **"error"** (default), **"ignore"** the property or **"reuse"** the D-Bus name for the member.

    - **Returns**

      dictionary of properties

    - **Return type**

      dict\[str, Any\]

  - **properties\_changed: tuple\[str, dict\[str, tuple\[str, Any\]\], list\[str\]\]**

    Signal when one of the objects properties changes.

    *sdbus.utils.parse.parse\_properties\_changed()* can be used to transform this signal data in to an easier to work with dictionary.

    Signal data is:

    - **Interface name (str)**

      Name of the interface where property changed

    - **Changed properties (dict\[str, tuple\[str, Any\]\])**

      Dictionary there keys are names of properties changed and values are variants of new value.

    - **Invalidated properties (list\[str\])**

      List of property names changed but no new value had been provided

  - **\_proxify(bus, service\_name, object\_path)**

    Begin proxying to a remote D-Bus object.

    - **Parameters**

      - •

        **service\_name** (*str*) -- Remote object D-Bus connection name. For example, systemd uses **org.freedesktop.systemd1**

      - •

        **object\_path** (*str*) -- Remote object D-Bus path. Should be a forward slash separated path. Starting object is usually **/**. Example: **/org/freedesktop/systemd/unit/dbus\_2eservice**

      - •

        **bus** (*SdBus*) -- Optional D-Bus connection object. If not passed the default D-Bus will be used.

  - **classmethod new\_proxy(bus, service\_name, object\_path)**

    Create new proxy object and bypass **\_\_init\_\_**.

    - **Parameters**

      - •

        **service\_name** (*str*) -- Remote object D-Bus connection name. For example, systemd uses **org.freedesktop.systemd1**

      - •

        **object\_path** (*str*) -- Remote object D-Bus path. Should be a forward slash separated path. Starting object is usually **/**. Example: **/org/freedesktop/systemd/unit/dbus\_2eservice**

      - •

        **bus** (*SdBus*) -- Optional D-Bus connection object. If not passed the default D-Bus will be used.

  - **export\_to\_dbus(object\_path, bus)**

    Object will appear and become callable on D-Bus.

    Returns a handle that can either be used as a context manager to remove the object from D-Bus or **.stop()** method of the handle can be called to remove object from D-Bus.

    Returns a handle that can be used to remove object from D-Bus by either using it as a context manager or by calling **.stop()** method of the handle.

    ```
    with dbus_object.export_to_dbus("/"):
        # dbus_object can be called from D-Bus inside this
        # with block.
        ...
    ...
    handle = dbus_object2.export_to_dbus("/")
    # dbus_object2 can be called from D-Bus between these statements
    handle.stop()
    ...
    dbus_object3.export_to_dbus("/")
    # dbus_object3 can be called from D-Bus until all references are
    # dropped.
    del dbus_object3
    ```

    If the handle is discarded the object will remain exported until it gets deallocated.

    *Changed in version 0.12.0:* Added a handle return.

    - **Parameters**

      - •

        **object\_path** (*str*) -- Object path that it will be available at.

      - •

        **bus** (*SdBus*) -- Optional D-Bus connection object. If not passed the default D-Bus will be used.

    - **Returns**

      Handle to control the export.

- **class sdbus.DbusObjectManagerInterfaceAsync(interface\_name)**

  This class is almost identical to *DbusInterfaceCommonAsync* but implements *ObjectManager* interface.

  Example of serving objects with ObjectManager:

  ```
  my_object_manager = DbusObjectManagerInterfaceAsync()
  my_object_manager.export_to_dbus('/object/manager')
  managed_object = DbusInterfaceCommonAsync()
  my_object_manager.export_with_manager('/object/manager/example', managed_object)
  ```

  - **async get\_managed\_objects()**

    Get the objects this object manager in managing.

    *sdbus.utils.parse.parse\_get\_managed\_objects()* can be used to make returned data easier to work with.

    - **Returns**

      Triple nested dictionary that contains all the objects paths with their properties values.

      dict\[ObjectPath, dict\[InterfaceName, dict\[PropertyName, PropertyValue\]\]\]

    - **Return type**

      dict\[str, dict\[str, dict\[str, Any\]\]\]

  - **interfaces\_added: tuple\[str, dict\[str, dict\[str, Any\]\]\]**

    Signal when a new object is added or and existing object gains a new interface.

    *sdbus.utils.parse.parse\_interfaces\_added()* can be used to make signal data easier to work with.

    Signal data is:

    - **Object path (str)**

      Path to object that was added or modified.

    - **Object interfaces and properties (dict\[str, dict\[str, Any\]\]\])**

      dict\[InterfaceName, dict\[PropertyName, PropertyValue\]\]

  - **interfaces\_removed: tuple\[str, list\[str\]\]**

    Signal when existing object or and interface of existing object is removed.

    *sdbus.utils.parse.parse\_interfaces\_removed()* can be used to make signal data easier to work with.

    Signal data is:

    - **Object path (str)**

      Path to object that was removed or modified.

    - **Interfaces list (list\[str\])**

      Interfaces names that were removed.

  - **export\_with\_manager(object\_path, object\_to\_export, bus)**

    Export object to D-Bus and emit a signal that it was added.

    ObjectManager must be exported first.

    Path should be a subpath of where ObjectManager was exported. Example, if ObjectManager exported to **/object/manager**, the managed object can be exported at **/object/manager/test**.

    ObjectManager will keep the reference to the object.

    Returns a handle that can be used to remove object from D-Bus and drop reference to it by either using it as a context manager or by calling **.stop()** method of the handle. Signal will be emitted once the object is stopped being exported.

    ```
    manager = DbusObjectManagerInterfaceAsync()
    manager.export_to_dbus('/object/manager')
    with manager.export_with_manager("/object/manager/example", dbus_object):
        # dbus_object can be called from D-Bus inside this
        # with block.
        ...
    # Removed signal will be emitted once the with block exits
    ...
    handle = manager.export_with_manager("/object/manager/example", dbus_object2)
    # dbus_object2 can be called from D-Bus between these statements
    handle.stop()
    # Removed signal will be emitted once the .stop() method is called
    ```

    If the handle is discarded the object will remain exported until it gets removed from manager with *remove\_managed\_object()* and the object gets deallocated.

    *Changed in version 0.12.0:* Added a handle return.

    - **Parameters**

      - •

        **object\_path** (*str*) -- Object path that it will be available at.

      - •

        **object\_to\_export** (*DbusInterfaceCommonAsync*) -- Object to export to D-Bus.

      - •

        **bus** (*SdBus*) -- Optional D-Bus connection object. If not passed the default D-Bus will be used.

    - **Raises**

      **RuntimeError** -- ObjectManager was not exported.

    - **Returns**

      Handle to control the export.

  - **remove\_managed\_object(managed\_object)**

    Emit signal that object was removed.

    Releases reference to the object.

    **CAUTION:**

    The object will still be accessible over D-Bus until all references to it will be removed.

    - **Parameters**

      **managed\_object** (*DbusInterfaceCommonAsync*) -- Object to remove from ObjectManager.

    - **Raises**

      - •

        **RuntimeError** -- ObjectManager was not exported.

      - •

        **KeyError** -- Passed object is not managed by ObjectManager.

### Decorators

- **@sdbus.dbus\_method\_async(\[input\_signature\[, result\_signature\[, flags\[, result\_args\_names\[, input\_args\_names\[, method\_name\]\]\]\]\]\])**

  Define a method.

  Underlying function must be a coroutine function.

  - **Parameters**

    - •

      **input\_signature** (*str*) -- D-Bus input signature. Defaults to "" meaning method takes no arguments. Required if you intend to connect to a remote object.

    - •

      **result\_signature** (*str*) -- D-Bus result signature. Defaults to "" meaning method returns empty reply on success. Required if you intend to serve the object.

    - •

      **flags** (*int*) --

      modifies behavior. No effect on remote connections. Defaults to 0 meaning no special behavior.

      See *Flags* .

    - •

      **result\_args\_names** (*Sequence\[str\]*) --

      sequence of result argument names.

      These names will show up in introspection data but otherwise have no effect.

      Sequence can be list, tuple, etc... Number of elements in the sequence should match the number of result arguments otherwise **SdBusLibraryError** will be raised.

      Defaults to result arguments being nameless.

    - •

      **input\_args\_names** (*Sequence\[str\]*) --

      sequence of input argument names.

      These names will show up in introspection data but otherwise have no effect.

      Sequence can be list, tuple, etc... Number of elements in the sequence should match the number of result arguments otherwise **RuntimeError** will be raised.

      If **result\_args\_names** has been passed when Python function argument names will be used otherwise input arguments will be nameless

    - •

      **method\_name** (*str*) -- Force specific D-Bus method name instead of being based on Python function name.

  Example:

  ```
  from sdbus import DbusInterfaceCommonAsync, dbus_method_async
  class ExampleInterface(DbusInterfaceCommonAsync,
                         interface_name='org.example.test'
                         ):
      # Method that takes a string
      # and returns uppercase of that string
      @dbus_method_async(
          input_signature='s',
          result_signature='s',
          result_args_names=('uppercased', )  # This is optional but
                                              # makes arguments have names in
                                              # introspection data.
      )
      async def upper(self, str_to_up: str) -> str:
          return str_to_up.upper()
  ```

- **@sdbus.dbus\_property\_async(property\_signature\[, flags\[, property\_name\]\])**

  Declare a D-Bus property.

  The underlying function has to be a regular **def** function.

  The property will be read-only or read/write based on if setter was declared.

  **WARNING:**

  Properties are supposed to be lightweight to get or set. Make sure property getter or setter does not perform heavy IO or computation as that will block other methods or properties.

  - **Parameters**

    - •

      **property\_signature** (*str*) -- Property D-Bus signature. Has to be a single type or container.

    - •

      **flags** (*int*) --

      modifies behavior. No effect on remote connections. Defaults to 0 meaning no special behavior.

      See *Flags* .

    - •

      **property\_name** (*str*) -- Force specific property name instead of constructing it based on Python function name.

  Example:

  ```
  from sdbus import DbusInterfaceCommonAsync, dbus_property_async
  class ExampleInterface(DbusInterfaceCommonAsync,
                         interface_name='org.example.test'
                         ):
      def __init__(self) -> None:
          # This is just a generic init
          self.i = 12345
          self.s = 'test'
      # Read only property. No setter defined.
      @dbus_property_async('i')
      def read_only_number(self) -> int:
          return self.i
      # Read/write property. First define getter.
      @dbus_property_async('s')
      def read_write_str(self) -> str:
          return self.s
      # Now create setter. Method name does not matter.
      @read_write_str.setter  # Use the property setter method as decorator
      def read_write_str_setter(self, new_str: str) -> None:
          self.s = new_str
  ```

  - **class sdbus.DbusPropertyAsync**

    Properties have following methods:

    - **@setter(set\_function)**

      Defines the setter function. This makes the property read/write instead of read-only.

      See example on how to use.

    - **@setter\_private(set\_function)**

      Defines the private setter function. The setter can be called locally but property will be read-only from D-Bus.

      Calling the setter locally will emit *properties\_changed* signal to D-Bus.

      *Changed in version 0.12.0:* can now be used in overrides.

    - **async get\_async()**

      Get the property value.

      The property can also be directly **await** ed instead of calling this method.

    - **async set\_async(new\_value)**

      Set property value.

- **@sdbus.dbus\_signal\_async(\[signal\_signature\[, signal\_args\_names\[, flags\[, signal\_name\]\]\]\])**

  Defines a D-Bus signal.

  Underlying function return type hint is used for signal type hints.

  - **Parameters**

    - •

      **signal\_signature** (*str*) -- signal D-Bus signature. Defaults to empty signal.

    - •

      **signal\_args\_names** (*Sequence\[str\]*) --

      sequence of signal argument names.

      These names will show up in introspection data but otherwise have no effect.

      Sequence can be list, tuple, etc... Number of elements in the sequence should match the number of result arguments otherwise **RuntimeError** will be raised.

      Defaults to result arguments being nameless.

    - •

      **flags** (*int*) --

      modifies behavior. No effect on remote connections. Defaults to 0 meaning no special behavior.

      See *Flags* .

    - •

      **signal\_name** (*str*) -- Forces specific signal name instead of being based on Python function name.

  Example:

  ```
  from sdbus import DbusInterfaceCommonAsync, dbus_signal_async
  class ExampleInterface(DbusInterfaceCommonAsync,
                         interface_name='org.example.signal'
                         ):
      @dbus_signal_async('s')
      def name_changed(self) -> str:
          raise NotImplementedError
  ```

  - **class sdbus.DbusSignalAsync**

    Signals have following methods:

    - **catch()**

      Catch D-Bus signals using the async generator for loop: **async for x in something.some\_signal.catch():**

      This is main way to await for new events.

      Both remote and local objects operate the same way.

      Signal objects can also be async iterated directly: **async for x in something.some\_signal**

    - **catch\_anywhere(service\_name, bus)**

      Catch signal independent of path. Yields tuple of path of the object that emitted signal and signal data.

      **async for path, data in something.some\_signal.catch\_anywhere():**

      This method can be called from both an proxy object and class. However, it cannot be called on local objects and will raise **NotImplementedError**.

      - **Parameters**

        - •

          **service\_name** (*str*) -- Service name of which signals belong to. Required if called from class. When called from proxy object the service name of the proxy will be used.

        - •

          **bus** (*str*) -- Optional D-Bus connection object. If not passed when called from proxy the bus connected to proxy will be used or when called from class default bus will be used.

    - **emit(args)**

      Emit a new signal with *args* data.

- **@sdbus.dbus\_method\_async\_override**

  Override the method.

  Method name should match the super class method name that you want to override.

  New method should take same arguments.

  You **must** add round brackets to decorator.

  Example:

  ```
  from sdbus import (DbusInterfaceCommonAsync, dbus_method_async
                     dbus_method_async_override)
  class ExampleInterface(DbusInterfaceCommonAsync,
                         interface_name='org.example.test'
                         ):
      # Original call
      @dbus_method_async('s', 's')
      async def upper(self, str_to_up: str) -> str:
          return str_to_up.upper()
  class ExampleOverride(ExampleInterface):
      @dbus_method_async_override()
      async def upper(self, str_to_up: str) -> str:
          return 'Upper: ' + str_to_up.upper()
  ```

- **@sdbus.dbus\_property\_async\_override**

  Override property.

  You **must** add round brackets to decorator.

  Example:

  ```
  from sdbus import (DbusInterfaceCommonAsync, dbus_property_async
                     dbus_property_async_override)
  class ExampleInterface(DbusInterfaceCommonAsync,
                         interface_name='org.example.test'
                         ):
      def __init__(self) -> None:
          self.s = 'aaaaaaaaa'
      # Original property
      @dbus_property_async('s')
      def str_prop(self) -> str:
          return self.s
      @str_prop.setter
      def str_prop_setter(self, new_s: str) -> None:
          self.s = new_s
  class ExampleOverride(ExampleInterface):
      @dbus_property_async_override()
      def str_prop(self) -> str:
          return 'Test property' + self.s
      # Setter needs to be decorated again to override
      @str_prop.setter
      def str_prop_setter(self, new_s: str) -> None:
          self.s = new_s.upper()
  ```

### Asyncio advanced topics

### Signals without data

D-Bus allows signals to not carry any data. Such signals have the type signature of **""**. (empty string)

To emit such signals the *emit* must be explicitly called with **None**.

Example of an empty signal:

```
from asyncio import new_event_loop
from sdbus import DbusInterfaceCommonAsync, dbus_signal_async
class ExampleInterface(
    DbusInterfaceCommonAsync,
    interface_name="org.example.signal"
):
    @dbus_signal_async("")
    def name_invalidated(self) -> None:
        raise NotImplementedError
test_object = ExampleInterface()
async def emit_empty_signal() -> None:
    test_object.export_to_dbus("/")
    test_object.name_invalidated.emit(None)
loop = new_event_loop()
loop.run_until_complete(emit_empty_signal())
```

### Exceptions

### Error name bound exceptions

These exceptions are bound to specific D-Bus error names. For example, *DbusFailedError* is bound to *org.freedesktop.DBus.Error.Failed* error name.

This means if the remote object sends an error message with this error name the Python will receive this exception.

When raised in a method callback an error message will be sent back to caller.

See *list of error exceptions*.

### New error bound exceptions

If you want to create a new error bound exception you should subclass it from *DbusFailedError* and provide a **unique** **dbus\_error\_name** attribute in the exception body definition.

Example:

```
class DbusExampleError(DbusFailedError):
    dbus_error_name = 'org.example.Error'
```

If **dbus\_error\_name** is not unique the **ValueError** will be raised.

Defining an exception will automatically bind incoming error message to this new exception.

Existing exceptions can be manually binded using *map\_exception\_to\_dbus\_error()* function.

### Python built-in exceptions

All Python built-in exceptions are mapped to D-Bus errors.

The D-Bus error name is created by appending **org.python.Error.** to the exception name.

For example, **AssertionError** is bound to **org.python.Error.AssertionError** name.

### Functions

- **sdbus.exceptions.map\_exception\_to\_dbus\_error(exception, dbus\_error\_name)**

  Map exception to a D-bus error. Error name must be unique.

  - **Parameters**

    - •

      **exception** (*Type\[Exception\]*) -- Exception to bind.

    - •

      **dbus\_error\_name** (*str*) -- D-Bus error name to bind to.

### Other exceptions

- **exception sdbus.exceptions.SdBusBaseError**

  Base exceptions for all exceptions defined in sdbus.

- **exception sdbus.exceptions.SdBusUnmappedMessageError**

  Message error that is unmapped.

  The exceptions argument is a tuple of error name and error message.

- **exception sdbus.exceptions.SdBusLibraryError**

  sd-bus library returned error.

  Exception message contains line number and the error name.

### Name request exceptions

These exceptions will be raise if an error related to ownership of D-Bus names occurs when calling *request\_default\_bus\_name\_async()* or *request\_default\_bus\_name()*.

- **exception sdbus.exceptions.SdBusRequestNameError**

  Common base exception for any name ownership error.

- **exception sdbus.exceptions.SdBusRequestNameInQueueError**

  Someone already owns the name but the request has been placed in queue.

- **exception sdbus.exceptions.SdBusRequestNameExistsError**

  Someone already owns the name.

- **exception sdbus.exceptions.SdBusRequestNameAlreadyOwnerError**

  The caller already owns the name.

### Error name exception list

- **exception sdbus.exceptions.DbusFailedError**

  Generic failure exception.

  Recommended to subclass to create a new exception.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.Failed**

    - **exception sdbus.exceptions.DbusNoMemoryError**

  Remote object is out of memory.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.NoMemory**

    - **exception sdbus.exceptions.DbusServiceUnknownError**

  No service with such name exists.

  Probably should only be raised by bus daemon.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.ServiceUnknown**

    - **exception sdbus.exceptions.DbusNameHasNoOwnerError**

  No process owns the name you called.

  Probably should only be raised by bus daemon.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.NameHasNoOwner**

    - **exception sdbus.exceptions.DbusNoReplyError**

  Timeout on reply.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.NoReply**

    - **exception sdbus.exceptions.DbusIOError**

  Input/Output error.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.IOError**

    - **exception sdbus.exceptions.DbusBadAddressError**

  Bad address.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.BadAddress**

    - **exception sdbus.exceptions.DbusNotSupportedError**

  Something is unsupported on this platform.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.NotSupported**

    - **exception sdbus.exceptions.DbusLimitsExceededError**

  Some resource was exhausted. (for example, file descriptors)

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.LimitsExceeded**

    - **exception sdbus.exceptions.DbusAccessDeniedError**

  Caller does not have enough privileges.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.AccessDenied**

    - **exception sdbus.exceptions.DbusAuthFailedError**

  Authentication failed.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.AuthFailed**

    - **exception sdbus.exceptions.DbusNoServerError**

  Unable to connect to bus.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.NoServer**

    - **exception sdbus.exceptions.DbusTimeoutError**

  Socket timeout.

  This is different from *DbusNoReplyError* as here the connection to bus timeout not the remote object not replying.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.Timeout**

    - **exception sdbus.exceptions.DbusNoNetworkError**

  No network access.

  Encountered you use D-Bus over TCP or SSH.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.NoNetwork**

    - **exception sdbus.exceptions.DbusAddressInUseError**

  Address in use.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.AddressInUse**

    - **exception sdbus.exceptions.DbusDisconnectedError**

  Disconnected from bus.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.Disconnected**

    - **exception sdbus.exceptions.DbusInvalidArgsError**

  Method call args are invalid.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.InvalidArgs**

    - **exception sdbus.exceptions.DbusFileNotFoundError**

  File not found.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.FileNotFound**

    - **exception sdbus.exceptions.DbusFileExistsError**

  Generic failure exception.

  Recommended to subclass to create a new exception.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.FileExists**

    - **exception sdbus.exceptions.DbusUnknownMethodError**

  Unknown D-Bus method.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.UnknownMethod**

    - **exception sdbus.exceptions.DbusUnknownObjectError**

  Unknown D-Bus object.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.UnknownObject**

    - **exception sdbus.exceptions.DbusUnknownInterfaceError**

  Unknown D-Bus interface.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.UnknownInterface**

    - **exception sdbus.exceptions.DbusUnknownPropertyError**

  Unknown D-Bus property.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.UnknownProperty**

    - **exception sdbus.exceptions.DbusPropertyReadOnlyError**

  D-Bus property is read only.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.PropertyReadOnly**

    - **exception sdbus.exceptions.DbusUnixProcessIdUnknownError**

  PID does not exists.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.UnixProcessIdUnknown**

    - **exception sdbus.exceptions.DbusInvalidSignatureError**

  Invalid D-Bus type signature.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.InvalidSignature**

    - **exception sdbus.exceptions.DbusInvalidFileContentError**

  Invalid file content.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.InvalidFileContent**

    - **exception sdbus.exceptions.DbusInconsistentMessageError**

  D-Bus message is malformed.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.InconsistentMessage**

    - **exception sdbus.exceptions.DbusMatchRuleNotFound**

  Match rule does not exist.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.MatchRuleNotFound**

    - **exception sdbus.exceptions.DbusMatchRuleInvalidError**

  Match rule is invalid.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.MatchRuleInvalid**

    - **exception sdbus.exceptions.DbusInteractiveAuthorizationRequiredError**

  Requires interactive authorization.

  - **dbus\_error\_name: str = org.freedesktop.DBus.Error.InteractiveAuthorizationRequired**

    ### Utilities

### Parsing utilities

Parse unweildy D-Bus structures in to Python native objects and names. Available under **sdbus.utils.parse** subpackage.

- **sdbus.utils.parse.parse\_properties\_changed(interface: InterfacesInputElements, properties\_changed\_data: DBUS\_PROPERTIES\_CHANGED\_TYPING, on\_unknown\_member: OnUnknownMember = 'error') -\> dict\[str, Any\]**

  Parse data from *properties\_changed* signal.

  Parses changed properties from a single D-Bus object. The object's interface class must be known in advance and passed as a first argument.

  Member names will be translated to python defined names. Invalidated properties will have a value of None.

  - **Parameters**

    - •

      **interface** -- Takes either D-Bus interface class or its object.

    - •

      **properties\_changed\_data** -- Tuple caught from signal.

    - •

      **on\_unknown\_member** -- If an unknown D-Bus property was encountered either raise an **"error"** (default), **"ignore"** the property or **"reuse"** the D-Bus name for the member.

  - **Returns**

    Dictionary of changed properties with keys translated to python names. Invalidated properties will have value of None.

- **sdbus.utils.parse.parse\_interfaces\_added(interfaces: InterfacesInput, interfaces\_added\_data: tuple\[str, dict\[str, dict\[str, Any\]\]\], on\_unknown\_interface: OnUnknownInterface = 'error', on\_unknown\_member: OnUnknownMember = 'error', \*, use\_interface\_subsets: bool = False) -\> tuple\[str, InterfacesBaseTypes \| None, dict\[str, Any\]\]**

  Parse data from *interfaces\_added* signal.

  Takes the possible interface classes and the signal data. Returns the path of new object, the class of the added object (if it matched one of passed interface classes) and the dictionary of python named properties and their values.

  The passed interfaces can be async or blocking, the class or an instantiated object, a single item or an iterable of interfaces.

  - **Parameters**

    - •

      **interfaces** -- Possible interfaces that were added.

    - •

      **interfaces\_added\_data** -- Tuple caught from signal.

    - •

      **on\_unknown\_interface** -- If an unknown D-Bus interface was encountered either raise an **"error"** (default) or return **"none"** instead of interface class.

    - •

      **on\_unknown\_member** -- If an unknown D-Bus property was encountered either raise an **"error"** (default), **"ignore"** the property or **"reuse"** the D-Bus name for the member.

    - •

      **use\_interface\_subsets** -- Use the subset of interfaces as a valid match. For example, the class that implements **org.example.foo** would be matched with an data consising of both **org.example.foo** and **org.example.bar**. The classes implementing more interfaces will have higher priority over the ones implementing fewer.

  - **Returns**

    Path of new added object, object's class (or **None**) and dictionary of python translated members and their values.

- **sdbus.utils.parse.parse\_interfaces\_removed(interfaces: InterfacesInput, interfaces\_removed\_data: tuple\[str, list\[str\]\], on\_unknown\_interface: OnUnknownInterface = 'error', \*, use\_interface\_subsets: bool = False) -\> tuple\[str, InterfacesBaseTypes \| None\]**

  Parse data from *interfaces\_added* signal.

  Takes the possible interface classes and the signal data. Returns the path and the matched class of removed object. (if it matched one of passed interface classes)

  The passed interfaces can be async or blocking, the class or an instantiated object, a single item or an iterable of interfaces.

  - **Parameters**

    - •

      **interfaces** -- Possible interfaces that were removed.

    - •

      **interfaces\_added\_data** -- Tuple caught from signal.

    - •

      **on\_unknown\_member** -- If an unknown D-Bus interface was encountered either raise an **"error"** (default) or return **"none"** instead of interface class.

    - •

      **use\_interface\_subsets** -- Use the subset of interfaces as a valid match. For example, the class that implements **org.example.foo** would be matched with an data consising of both **org.example.foo** and **org.example.bar**. The classes implementing more interfaces will have higher priority over the ones implementing fewer.

  - **Returns**

    Path of removed object and object's class (or **None**).

- **sdbus.utils.parse.parse\_get\_managed\_objects(interfaces: InterfacesInput, managed\_objects\_data: dict\[str, dict\[str, dict\[str, Any\]\]\], on\_unknown\_interface: OnUnknownInterface = 'error', on\_unknown\_member: OnUnknownMember = 'error', \*, use\_interface\_subsets: bool = False) -\> ParseGetManaged**

  Parse data from *get\_managed\_objects* call.

  Takes the possible interface classes and the method's returned data. Returns a dictionary where keys a paths of the managed objects and value is a tuple of class of the object and dictionary of its python named properties and their values.

  The passed interfaces can be async or blocking, the class or an instantiated object, a single item or an iterable of interfaces.

  - **Parameters**

    - •

      **interfaces** -- Possible interfaces of the managed objects.

    - •

      **managed\_objects\_data** -- Data returned by **get\_managed\_objects** call.

    - •

      **on\_unknown\_interface** -- If an unknown D-Bus interface was encountered either raise an **"error"** (default) or return **"none"** instead of interface class.

    - •

      **on\_unknown\_member** -- If an unknown D-Bus property was encountered either raise an **"error"** (default), **"ignore"** the property or **"reuse"** the D-Bus name for the member.

    - •

      **use\_interface\_subsets** -- Use the subset of interfaces as a valid match. For example, the class that implements **org.example.foo** would be matched with an data consising of both **org.example.foo** and **org.example.bar**. The classes implementing more interfaces will have higher priority over the ones implementing fewer.

  - **Returns**

    Dictionary where keys are paths and values are tuples of managed objects classes and their properties data.

  *New in version 0.12.0.*

### Inspect utilities

Inspect D-Bus objects and retrieve their D-Bus related attributes such as D-Bus object paths and etc... Available under **sdbus.utils.inspect** subpackage.

- **sdbus.utils.inspect.inspect\_dbus\_path(obj: DbusInterfaceBase \| DbusInterfaceBaseAsync, bus: SdBus \| None = None) -\> str**

  Return the D-Bus path of an object.

  If called on a D-Bus proxy returns path of the proxied object.

  If called on a local D-Bus object returns the exported D-Bus path. If object is not exported raises **LookupError**.

  If called on an object that is unrelated to D-Bus raises **TypeError**.

  The object's path is inspected in the context of the given bus and if the object is attached to a different bus the **LookupError** will be raised. If the bus argument is not given or is **None** the default bus will be checked against.

  - **Parameters**

    - •

      **obj** -- Object to inspect.

    - •

      **bus** -- Bus to inspect against. If not given or is **None** the default bus will be used.

  - **Returns**

    D-Bus path of the object.

  *New in version 0.13.0.*

### Examples

### Asyncio client and server

In this example we create a simple example server and client.

There are 3 files:

- •

  **example\_interface.py** File that contains the interface definition.

- •

  **example\_server.py** Server.

- •

  **example\_client.py** Client.

**example\_interface.py** file:

```
from sdbus import (DbusInterfaceCommonAsync, dbus_method_async,
                       dbus_property_async, dbus_signal_async)
# This is file only contains interface definition for easy import
# in server and client files
class ExampleInterface(
    DbusInterfaceCommonAsync,
    interface_name='org.example.interface'
):
    @dbus_method_async(
        input_signature='s',
        result_signature='s',
    )
    async def upper(self, string: str) -> str:
        return string.upper()
    @dbus_property_async(
        property_signature='s',
    )
    def hello_world(self) -> str:
        return 'Hello, World!'
    @dbus_signal_async(
        signal_signature='i'
    )
    def clock(self) -> int:
        raise NotImplementedError
```

**example\_server.py** file:

```
from asyncio import get_event_loop, sleep
from random import randint
from time import time
from example_interface import ExampleInterface
from sdbus import request_default_bus_name_async
loop = get_event_loop()
export_object = ExampleInterface()
async def clock() -> None:
    """
    This coroutine will sleep a random time and emit a signal with current clock
    """
    while True:
        await sleep(randint(2, 7))  # Sleep a random time
        current_time = int(time())  # The interface we defined uses integers
        export_object.clock.emit(current_time)
async def startup() -> None:
    """Perform async startup actions"""
    # Acquire a known name on the bus
    # Clients will use that name to address to this server
    await request_default_bus_name_async('org.example.test')
    # Export the object to D-Bus
    export_object.export_to_dbus('/')
loop.run_until_complete(startup())
task_clock = loop.create_task(clock())
loop.run_forever()
```

**example\_client.py** file:

```
from asyncio import get_event_loop
from example_interface import ExampleInterface
# Create a new proxy object
example_object = ExampleInterface.new_proxy('org.example.test', '/')
async def print_clock() -> None:
    # Use async for loop to print clock signals we receive
    async for x in example_object.clock:
        print('Got clock: ', x)
async def call_upper() -> None:
    s = 'test string'
    s_after = await example_object.upper(s)
    print('Initial string: ', s)
    print('After call: ', s_after)
async def get_hello_world() -> None:
    print('Remote property: ', await example_object.hello_world)
loop = get_event_loop()
# Always binds your tasks to a variable
task_upper = loop.create_task(call_upper())
task_clock = loop.create_task(print_clock())
task_hello_world = loop.create_task(get_hello_world())
loop.run_forever()
```

Start server before client. **python example\_server.py**

In separated terminal start client. **python example\_client.py**

Use CTRL-C to close client and server.

You can also use **ExampleInterface** as a local object:

```
from asyncio import run
from example_interface import ExampleInterface
example_object = ExampleInterface()
async def test() -> None:
    print(await example_object.upper('test'))
    print(await example_object.hello_world)
run(test())
```

### Interfaces repository

python-sdbus includes two namespace packages **sdbus\_async** and **sdbus\_block** which are used for proxies.

For example, D-Bus daemon interface (which comes by default) can be found under **sdbus\_async.dbus\_daemon** for async binds and **sdbus\_block.dbus\_daemon** for blocking binds.

### Known proxies

### D-Bus daemon interface

- **class sdbus\_async.dbus\_daemon.FreedesktopDbus(bus: SdBus \| None = None)**

  D-Bus daemon.

  This is the D-Bus daemon interface. Used for querying D-Bus state.

  D-Bus interface object path and service name is predetermined. (at **'org.freedesktop.DBus'**, **'/org/freedesktop/DBus'**)

  - **Parameters**

    **bus** (*SdBus*) -- Optional D-Bus connection. If not passed the default D-Bus will be used.

  - **async get\_connection\_pid(service\_name: str) -\> int**

    **D-Bus Method**

    Get process ID that owns a specified name.

    - **Parameters**

      **service\_name** (*str*) -- Service name to query.

    - **Returns**

      PID of name owner

    - **Raises**

      *DbusNameHasNoOwnerError* -- Nobody owns that name

  - **async get\_connection\_uid(service\_name: str) -\> int**

    **D-Bus Method**

    Get process user ID that owns a specified name.

    - **Parameters**

      **service\_name** (*str*) -- Service name to query.

    - **Returns**

      User ID of name owner

    - **Raises**

      *DbusNameHasNoOwnerError* -- Nobody owns that name

  - **async get\_id() -\> str**

    **D-Bus Method**

    Returns machine id where bus is run. (stored in **/etc/machine-id**)

    - **Returns**

      Machine id

  - **async get\_name\_owner(service\_name: str) -\> str**

    **D-Bus Method**

    Returns unique bus name (i.e. **':1.94'**) for given service name.

    - **Parameters**

      **service\_name** (*str*) -- Service name to query.

    - **Returns**

      Unique bus name.

    - **Raises**

      *DbusNameHasNoOwnerError* -- Nobody owns that name

  - **async list\_activatable\_names() -\> list\[str\]**

    **D-Bus Method**

    Lists all activatable services names.

    - **Returns**

      List of all names.

  - **async list\_names() -\> list\[str\]**

    **D-Bus Method**

    List all services and connections currently of the bus.

    - **Returns**

      List of all current names.

  - **async name\_has\_owner(service\_name: str) -\> bool**

    **D-Bus Method**

    Return True if someone already owns the name, False if nobody does.

    - **Parameters**

      **service\_name** (*str*) -- Service name to query.

    - **Returns**

      Is the name owned?

  - **async start\_service\_by\_name(service\_name: str, flags: int = 0) -\> int**

    **D-Bus Method**

    Starts a specified service.

    Flags parameter is not used currently and should be omitted or set to 0.

    - **Parameters**

      - •

        **service\_name** (*str*) -- Service name to start.

      - •

        **flags** (*int*) -- Not used. Omit or pass 0.

    - **Returns**

      1 on success, 2 if already started.

  - **features**

    **D-Bus property**

    **Python type**: *list\[str\]*

    **D-Bus type**: as

    List of D-Bus daemon features.

    Features include:

    - •

      'AppArmor' - Messages filtered by AppArmor on this bus.

    - •

      'HeaderFiltering' - Messages are filtered if they have incorrect                               header fields.

    - •

      'SELinux' - Messages filtered by SELinux on this bus.

    - •

      'SystemdActivation' - services activated by systemd if their                                .service file specifies a D-Bus name.

  - **interfaces**

    **D-Bus property**

    **Python type**: *list\[str\]*

    **D-Bus type**: as

    Extra D-Bus daemon interfaces

  - **name\_acquired**

    **D-Bus signal**

    **Python type**: *str*

    **D-Bus type**: s

    Signal when current process acquires a bus name.

  - **name\_lost**

    **D-Bus signal**

    **Python type**: *str*

    **D-Bus type**: s

    Signal when current process loses a bus name.

  - **name\_owner\_changed**

    **D-Bus signal**

    **Python type**: *tuple\[str, str, str\]*

    **D-Bus type**: sss

    Signal when some name on a bus changes owner.

    Is a tuple of:

    - •

      The name that acquired or lost

    - •

      Old owner (by unique bus name) or empty string if no one owned it

    - •

      New owner (by unique bus name) or empty string if no one owns it now

This list contains the known python-sdbus interface collections:

- •

  *D-Bus daemon interface*. Built-in.

- •

  *Notifications*.

- •

  *NetworkManager*.

- •

  *Secrets*.

### Interface code generator

Python-sdbus is able to generate the interfaces code from the D-Bus introspection XML. (either from a file or live object on D-Bus) Currently async interfaces code is generated by default. Blocking interfaces can be generated by passing **--block** option.

Running code generator requires *Jinja* to be installed.

**WARNING:**

Do NOT send the generator result to **exec()** function. Interface code MUST be inspected before running.

The generated interfaces code will be syntactically correct but NOT stylistically. It is recommended running a code formatter on the generated code. (for example **black**)

### Generating from XML files

To run generator on files (such as found under **/usr/share/dbus-1/interfaces/** folder) execute the **sdbus** module with **gen-from-file** first argument and file paths to introspection XML files:

```
python -m sdbus gen-from-file /usr/share/dbus-1/interfaces/org.gnome.Shell.Screenshot.xml
```

The generated interface code will be printed in to stdout. You can use shell redirection **\>** to save it in to file.

Multiple interface files can be passed which generates a file containing multiple interfaces.

### Generating from run-time introspection

To run generator on some service on the D-Bus execute the **sdbus** module with **gen-from-connection** first argument, the service connection name as second and one or more object paths:

```
python -m sdbus gen-from-connection org.freedesktop.systemd1 /org/freedesktop/systemd1
```

The generated interface code will be printed in to stdout. You can use shell redirection **\>** to save it in to file.

Multiple object paths can be passed which generates a file containing all interfaces encountered in the objects.

Pass **--system** option to use system bus instead of session bus.

### Renaming interfaces and members

*New in version 0.13.0.*

Some interface and member names might conflict with Python keywords when converted from D-Bus introspection to Python code by gerator. The CLI interface allow to override the particular interface and member names using the **--select-\*** and **--set-name** options. The selector options move the cursor to a particular interface and member

Available override options:

- •

  - **--set-name**

    Sets the name of currently selected element as it would be in generated Python code. Can be used if either interface or member is selected.

- •

  - **--select-interface**

    Selects the interface using its D-Bus name.

- •

  - **--select-method**

    Selects the method using its D-Bus name. An interface must be selected first.

- •

  - **--select-property**

    Selects the property using its D-Bus name. An interface must be selected first.

- •

  - **--select-signal**

    Selects the signal using its D-Bus name. An interface must be selected first.

For example, an **org.example.Interface** interface has a property called **Class**. When automatically converted the name will become **class** which is a reserved Python keyword.

Using these CLI options it is possible to override the name of the property and class:

```
python -m sdbus gen-from-file \
    org.example.interface.xml \
        --select-interface org.example.Interface \
            --set-name Example \
            --select-property Class \
                --set-name example_class
```

This will generate following Python code:

```
class Example:
    @dbus_property_async(
        property_signature="s",
    )
    def example_class(self) -> str:
        raise NotImplementedError
```

### Autodoc extensions

Python-sdbus has an extension for Sphinx autodoc that can document D-Bus interfaces.

To use it include **"sdbus.autodoc"** extension in your **conf.py** file.

```
extensions = ['sdbus.autodoc']
```

The extension can document interface class bodies. For example, *python-sdbus-networkmanager* uses it to document the classes.

```
.. autoclass:: sdbus_async.networkmanager.NetworkManagerDeviceBluetoothInterfaceAsync
    :members:
```

**WARNING:**

Autodoc extension is early in development and has multiple issues. For example, the inheritance **:inherited-members:** does not work on the D-Bus elements.

### Writing docstrings

The D-Bus methods should be documented same way as the regular function would. See *Sphinx documentation on possible fields*

Example docstring for a D-Bus method:

```
@dbus_method_async('s', method_name='GetConnectionUnixProcessID')
async def get_connection_pid(self, service_name: str) -> int:
    """Get process ID that owns a specified name.
    :param service_name: Service name to query.
    :return: PID of name owner
    :raises DbusNameHasNoOwnerError: Nobody owns that name
    """
    raise NotImplementedError
```

D-Bus properties and signals will be annotated with type taken from the stub function.

```
@dbus_property_async('as')
def features(self) -> list[str]:
    """List of D-Bus daemon features.
    Features include:
    * 'AppArmor' - Messages filtered by AppArmor on this bus.
    * 'HeaderFiltering' - Messages are filtered if they have incorrect \
                          header fields.
    * 'SELinux' - Messages filtered by SELinux on this bus.
    * 'SystemdActivation' - services activated by systemd if their \
                           .service file specifies a D-Bus name.
    """
    raise NotImplementedError
```

No parameters are supported at the moment for properties and signals.

### Unit testing

Python-sdbus provides several utilities to enable unit testing.

- **class sdbus.unittest.IsolatedDbusTestCase**

  Extension of *unittest.IsolatedAsyncioTestCase* from standard library.

  Creates an isolated instance of session D-Bus. The D-Bus will be closed and cleaned up after tests are finished.

  Requires **dbus-daemon** executable be installed.

  Example:

  ```
  from sdbus import DbusInterfaceCommonAsync, dbus_method_async
  from sdbus.unittest import IsolatedDbusTestCase
  class TestInterface(DbusInterfaceCommonAsync,
                      interface_name='org.test.test',
                      ):
      @dbus_method_async("s", "s")
      async def upper(self, string: str) -> str:
          """Uppercase the input"""
          return string.upper()
  def initialize_object() -> tuple[TestInterface, TestInterface]:
      test_object = TestInterface()
      test_object.export_to_dbus('/')
      test_object_connection = TestInterface.new_proxy(
      "org.example.test", '/')
      return test_object, test_object_connection
  class TestProxy(IsolatedDbusTestCase):
      async def asyncSetUp(self) -> None:
          await super().asyncSetUp()
          await self.bus.request_name_async("org.example.test", 0)
      async def test_method_kwargs(self) -> None:
          test_object, test_object_connection = initialize_object()
          self.assertEqual(
              'TEST',
              await test_object_connection.upper('test'),
          )
  ```

  - **bus: SdBus**

    Bus instance connected to isolated D-Bus environment.

    It is also set as a default bus.

  - **assertDbusSignalEmits(signal, timeout=1)**

    Assert that a given signal was emitted at least once within the given timeout.

    - **Parameters**

      - •

        **signal** -- D-Bus signal object. Can be a signal from either local or proxy object.

      - •

        **timeout** (*Union\[int, float\]*) -- Maximum wait time until first captured signal.

    Should be used as an async context manager. The context manager exits as soon as first signal is captured.

    The object returned by context manager has following attributes:

    - **output: list\[Any\]**

      List of captured data.

    Example:

    ```
    async with self.assertDbusSignalEmits(test_object.test_signal) as signal_record:
        test_object.test_signal.emit("test")
    self.assertEqual(["test"], signal_record.output)
    ```

    *New in version 0.12.0.*

### API Index

### Common:

**get\_default\_bus()**

**request\_default\_bus\_name\_async()**

**set\_default\_bus()**

*decode\_object\_path()*

*encode\_object\_path()*

*sd\_bus\_open\_system()*

*sd\_bus\_open\_user()*

*DbusDeprecatedFlag*

*DbusHiddenFlag*

*DbusNoReplyFlag*

*DbusPropertyConstFlag*

*DbusPropertyEmitsChangeFlag*

*DbusPropertyEmitsInvalidationFlag*

*DbusPropertyExplicitFlag*

*DbusSensitiveFlag*

*DbusUnprivilegedFlag*

### Asyncio:

*DbusInterfaceCommonAsync*

*dbus\_method\_async()*

*dbus\_method\_async\_override()*

*dbus\_property\_async()*

*dbus\_property\_async\_override()*

*dbus\_signal\_async()*

### Blocking:

*DbusInterfaceCommon*

*dbus\_method()*

*dbus\_property()*

### Exceptions:

*exceptions.DbusAccessDeniedError*

*exceptions.DbusAccessDeniedError*

*exceptions.DbusAddressInUseError*

*exceptions.DbusAuthFailedError*

*exceptions.DbusBadAddressError*

*exceptions.DbusDisconnectedError*

*exceptions.DbusFailedError*

*exceptions.DbusFileExistsError*

*exceptions.DbusFileNotFoundError*

*exceptions.DbusInconsistentMessageError*

*exceptions.DbusInteractiveAuthorizationRequiredError*

*exceptions.DbusInvalidArgsError*

*exceptions.DbusInvalidFileContentError*

*exceptions.DbusInvalidSignatureError*

*exceptions.DbusIOError*

*exceptions.DbusLimitsExceededError*

*exceptions.DbusMatchRuleInvalidError*

*exceptions.DbusMatchRuleNotFound*

*exceptions.DbusNameHasNoOwnerError*

*exceptions.DbusNoMemoryError*

*exceptions.DbusNoNetworkError*

*exceptions.DbusNoReplyError*

*exceptions.DbusNoServerError*

*exceptions.DbusNotSupportedError*

*exceptions.DbusPropertyReadOnlyError*

*exceptions.DbusServiceUnknownError*

*exceptions.DbusTimeoutError*

*exceptions.DbusUnixProcessIdUnknownError*

*exceptions.DbusUnknownInterfaceError*

*exceptions.DbusUnknownMethodError*

*exceptions.DbusUnknownObjectError*

*exceptions.DbusUnknownPropertyError*

*exceptions.SdBusBaseError*

*exceptions.SdBusLibraryError*

*exceptions.SdBusUnmappedMessageError*

*exceptions.map\_exception\_to\_dbus\_error()*

*exceptions.SdBusRequestNameError*

*exceptions.SdBusRequestNameInQueueError*

*exceptions.SdBusRequestNameExistsError*

*exceptions.SdBusRequestNameAlreadyOwnerError*

- •

  *Index*

- •

  *API Index*

- •

  *Search Page*

## AUTHOR

igo95862
