sdbus
sdbus is a modern, asynchronous Python D-Bus library built upon `sd-bus` from `libsystemd`. It provides a robust, low-level interface for D-Bus communication, supporting both system and session buses. Currently at version 0.14.2, it maintains an active release cycle with regular updates addressing bug fixes and feature enhancements.
Warnings
- breaking Starting with version 0.14.0, sdbus requires Python 3.9 or higher. Version 0.13.0 was the last to support Python 3.8.
- gotcha In version 0.14.0, the default bus handling was changed. Previously, context-local variables were used, often leading to new buses being opened unnecessarily. This might change behavior if your application implicitly relies on the old context-local default bus mechanism.
- breaking Version 0.12.0 significantly reworked internal undocumented classes and functions. If your code directly interacted with these internal APIs, it might break.
- breaking For binary PyPI wheels of version 0.14.0 and later, there are increased minimum requirements: glibc 2.28+ (e.g., Debian 10+, Ubuntu 18.10+, RHEL/CentOS 8+) and pip 20.3+.
- gotcha Version 0.14.2 fixed a segmentation fault that occurred if an export handle outlived the exported object. Older versions might crash under these specific circumstances.
Install
-
pip install sdbus
Imports
- SystemBus
from sdbus.bus import SystemBus
- SessionBus
from sdbus.bus import SessionBus
- DbusInterface
from sdbus import DbusInterface
- dbus_method
from sdbus import dbus_method
- dbus_property
from sdbus import dbus_property
Quickstart
import sdbus
import asyncio
class MyService(sdbus.DbusInterface):
DBUS_NAME = "org.example.MyService"
DBUS_PATH = "/org/example/MyObject"
DBUS_INTERFACE = "org.example.MyInterface"
@sdbus.dbus_method
def SayHello(self, name: str) -> str:
return f"Hello, {name}!"
async def main():
# Connect to the System Bus
bus = await sdbus.bus.SystemBus().connect()
# Export an instance of MyService
service_object = MyService()
bus.export(service_object)
# Request a D-Bus name for the service
await bus.request_name(MyService.DBUS_NAME)
print(f"Service '{MyService.DBUS_NAME}' exported on path '{MyService.DBUS_PATH}'.")
print("To test, run in another terminal (with busctl):")
print(f"busctl call {MyService.DBUS_NAME} {MyService.DBUS_PATH} {MyService.DBUS_INTERFACE} SayHello s 'World'")
print("Press Ctrl+C to exit.")
# Keep the service running indefinitely
await asyncio.Event().wait()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nService stopped.")