The Next Generation DBus Library for Python

Emily Techscribe Avatar

·

Introducing python-dbus-next: The Next Generation DBus Library for Python

Are you a developer looking for a powerful and comprehensive library to integrate your applications into Linux desktop and mobile environments? Look no further! Allow us to introduce python-dbus-next, the next great DBus library for Python. In this article, we will explore its key features, installation process, and demonstrate how to use it for both client and service interfaces.

What is python-dbus-next?

python-dbus-next is a Python library that aims to be a fully featured high-level DBus library primarily geared towards integration of applications into Linux desktop and mobile environments. It allows developers to integrate their applications into desktop environments by implementing common DBus standard interfaces or creating custom plugin interfaces. Moreover, desktop users can leverage this library to create their own scripts and utilities for customization of their desktop environment.

Key Features

python-dbus-next plans to improve over other DBus libraries for Python in the following ways:

  • Zero dependencies and pure Python 3.
  • Support for multiple IO backends including asyncio and the GLib main loop.
  • Nonblocking IO suitable for GUI development.
  • Target the latest language features of Python for beautiful services and clients.
  • Complete implementation of the DBus type system without ever guessing types.
  • Integration tests for all features of the library.
  • Completely documented public API.

Installation

Getting started with python-dbus-next is quick and easy. Simply follow these steps:

  1. Install the library from PyPi using pip3:

bash
pip3 install dbus-next

That’s it! You are now ready to explore the power of python-dbus-next in your projects.

The Client Interface

The client interface of python-dbus-next allows you to interact with services on the bus by constructing proxy objects. These proxy objects enable you to call methods, get and set properties, and listen to signals. Let’s take a look at an example that demonstrates how to control a media player using the MPRIS DBus interface:

“`python

Import the required modules

from dbus_next.aio import MessageBus
import asyncio

Initialize the event loop

loop = asyncio.get_event_loop()

Define the main function

async def main():
# Connect to the MessageBus
bus = await MessageBus().connect()

# Introspect the media player interface
introspection = await bus.introspect('org.mpris.MediaPlayer2.vlc', '/org/mpris/MediaPlayer2')

# Get the proxy object for the media player interface
obj = bus.get_proxy_object('org.mpris.MediaPlayer2.vlc', '/org/mpris/MediaPlayer2', introspection)
player = obj.get_interface('org.mpris.MediaPlayer2.Player')
properties = obj.get_interface('org.freedesktop.DBus.Properties')

# Call methods on the interface (this causes the media player to play)
await player.call_play()

# Get and set properties
volume = await player.get_volume()
print(f'current volume: {volume}, setting to 0.5')
await player.set_volume(0.5)

# Listen to signals
def on_properties_changed(interface_name, changed_properties, invalidated_properties):
    for changed, variant in changed_properties.items():
        print(f'property changed: {changed} - {variant.value}')

properties.on_properties_changed(on_properties_changed)

await loop.create_future()

Run the main function

loop.run_until_complete(main())
“`

The above example demonstrates how python-dbus-next simplifies the process of interacting with DBus services. It enables you to control a media player by calling methods, getting and setting properties, and listening to signals.

The Service Interface

If you’re looking to define a service on the bus, python-dbus-next provides the ServiceInterface class. By using this class and decorating class methods, you can specify DBus methods, properties, and signals with their type signatures. Here’s an example that shows how to define and export a service interface:

“`python

Import the required modules

from dbus_next.service import ServiceInterface, method, dbus_property, signal, Variant
from dbus_next.aio import MessageBus

import asyncio

Define the ExampleInterface class

class ExampleInterface(ServiceInterface):
def init(self, name):
super().init(name)
self._string_prop = ‘kevin’

@method()
def Echo(self, what: 's') -> 's':
    return what

@method()
def GetVariantDict() -> 'a{sv}':
    return {
        'foo': Variant('s', 'bar'),
        'bat': Variant('x', -55),
        'a_list': Variant('as', ['hello', 'world'])
    }

@dbus_property()
def string_prop(self) -> 's':
    return self._string_prop

@string_prop.setter
def string_prop_setter(self, val: 's'):
    self._string_prop = val

@signal()
def signal_simple(self) -> 's':
    return 'hello'

Define the main function

async def main():
# Connect to the MessageBus
bus = await MessageBus().connect()
interface = ExampleInterface(‘test.interface’)

# Export the service on the bus
bus.export('/test/path', interface)

# Request a name from D-Bus
await bus.request_name('test.name')

# Wait indefinitely
await asyncio.get_event_loop().create_future()

Run the main function

asyncio.get_event_loop().run_until_complete(main())
“`

The above example demonstrates how to define a service interface using python-dbus-next. It showcases how to define methods, properties, and signals, and how to export the service on the bus.

The Low-Level Interface

If you prefer working with DBus messages directly, python-dbus-next provides a low-level interface that allows you to interact with DBus messages at a lower level of abstraction. Here’s an example that demonstrates how to use the low-level interface:

“`python

Import the required modules

from dbus_next.message import Message, MessageType
from dbus_next.aio import MessageBus

import asyncio
import json

Initialize the event loop

loop = asyncio.get_event_loop()

Define the main function

async def main():
# Connect to the MessageBus
bus = await MessageBus().connect()

# Call a method on the D-Bus interface
reply = await bus.call(
    Message(destination='org.freedesktop.DBus',
            path='/org/freedesktop/DBus',
            interface='org.freedesktop.DBus',
            member='ListNames'))

if reply.message_type == MessageType.ERROR:
    raise Exception(reply.body[0])

print(json.dumps(reply.body[0], indent=2))

Run the main function

loop.run_until_complete(main())
“`

The above example demonstrates how to use the low-level interface of python-dbus-next. It showcases how to call a method on a D-Bus interface and retrieve the response.

Projects that use python-dbus-next

python-dbus-next is already being used by various projects. Some notable examples include:

Conclusion

In this article, we introduced python-dbus-next, the next generation DBus library for Python. We explored its key features, installation process, and demonstrated how to use it for both client and service interfaces. Whether you are a desktop application developer or a desktop user looking to customize your environment, python-dbus-next is the perfect tool for integrating your applications into Linux desktop and mobile environments. So why wait? Start using python-dbus-next in your projects today and unlock the full potential of DBus integration.

Contributing

Contributions are welcome! If you’d like to contribute to python-dbus-next, visit the Github repository for more information. Before committing your changes, make sure to run the provided make command to run the linter, code formatter, and the test suite.

Copyright

You can use python-dbus-next under the MIT license. For more information, see the LICENSE file in the Github repository.

Leave a Reply

Your email address will not be published. Required fields are marked *