dbus-next
dbus-next is a pure Python 3 library for the D-Bus message bus system, designed for interprocess communication in Linux desktop and mobile environments. It boasts zero dependencies and offers first-class asyncio support, along with an optional GLib main loop backend. It's a modern alternative to older D-Bus bindings, providing high-level client and service interfaces, and is currently at version 0.2.3 with an active development and release cadence.
Common errors
-
AttributeError: 'MessageBus' object has no attribute 'session_bus'
cause Attempting to use deprecated convenience constructors for the message bus after version 0.1.1.fixReplace `MessageBus.session_bus()` or `MessageBus.system_bus()` with `await MessageBus().connect()` or `await MessageBus(bus_type=BusType.SYSTEM).connect()` respectively. -
ValueError: method parameters must specify the dbus type string as an annotation
cause A method, property getter/setter, or signal in a `ServiceInterface` subclass has not been annotated with a D-Bus type signature string.fixAdd appropriate D-Bus type signature string annotations to all parameters and return values of service interface methods. Example: `def my_method(self, name: 's') -> 's':`. -
TypeError: object 'coroutine' can't be used in 'await' expression
cause Attempting to use the result of an awaitable function (like `MessageBus().connect()`) without actually `await`ing it.fixEnsure that `MessageBus().connect()` is called with the `await` keyword: `bus = await MessageBus().connect()`. -
dbus_next.errors.InterfaceNotFoundError: Cannot get interface 'org.mpris.MediaPlayer2.Player' on object at path '/org/mpris/MediaPlayer2'
cause The D-Bus service or interface you are trying to connect to is not running, not exporting the specified interface, or the bus name/object path is incorrect.fixVerify that the D-Bus service you intend to interact with is running and correctly exporting the expected interface at the specified object path. Use `qdbusviewer` or `busctl` to inspect available services and interfaces on your system.
Warnings
- breaking The convenience constructors `MessageBus.session_bus()` and `MessageBus.system_bus()` were removed in version 0.1.1.
- gotcha When defining service methods, properties, or signals, all parameters and return values must be explicitly annotated with D-Bus type signature strings.
- gotcha The `MessageBus().connect()` call is an awaitable coroutine and must be `await`ed.
- gotcha Handling Unix file descriptors (type 'h') requires explicit configuration and manual management.
Install
-
pip install dbus-next
Imports
- MessageBus
from dbus_next.aio import MessageBus
- Variant
from dbus_next import Variant
- ServiceInterface
from dbus_next.service import (ServiceInterface, method, dbus_property, signal)
- MessageBus (legacy)
from dbus_next import MessageBus
from dbus_next.aio import MessageBus
Quickstart
import asyncio
import os
from dbus_next.aio import MessageBus
async def main():
bus = await MessageBus().connect() # Connect to the session bus
# Example: Introspect and interact with a media player (MPRIS)
# Replace 'org.mpris.MediaPlayer2.vlc' with your player's bus name if different
player_bus_name = os.environ.get('DBUS_PLAYER_NAME', 'org.mpris.MediaPlayer2.vlc')
player_object_path = os.environ.get('DBUS_PLAYER_PATH', '/org/mpris/MediaPlayer2')
try:
introspection = await bus.introspect(player_bus_name, player_object_path)
obj = bus.get_proxy_object(player_bus_name, player_object_path, introspection)
player_interface = obj.get_interface('org.mpris.MediaPlayer2.Player')
# Call a method (e.g., Play)
print(f"Calling Play on {player_bus_name}...")
await player_interface.call_play()
print("Play called.")
# Get a property (e.g., PlaybackStatus)
status = await player_interface.get_playback_status()
print(f"Current playback status: {status}")
except Exception as e:
print(f"Could not interact with media player (is one running?): {e}")
finally:
bus.disconnect()
if __name__ == '__main__':
asyncio.run(main())