Package: sdbus
Modern Python library for D-BusFeatures:Asyncio and blocking calls.Type hints. (mypy --strictcompatible)No Python 2 legacy.Based on fast sd-bus from systemd. (also supports elogind)Unified client/server interface classes. Write interface once!D-Bus methods can have keyword and default arguments.See thedocumentationfor tutorial and API reference.List of implemented interfacesD-Bus (built-in)Freedesktop NotificationsNetwork ManagerFreedesktop SecretsMore incoming. (systemd, Bluez, screen saver... )Community interfacessystemd(by@bernhardkaindl)modemmanager(by@zhanglongqi)StabilityPython-sdbus is under development and its API is not stable. Generally
anything documented in the official documentation is considered
stable but might be deprecated. Using deprecated feature will
raise a warning and the feature will be eventually removed.See thedeprecations list.If there is a feature that is not documented but you would like to use
please open a new issue.RequirementsBinary package from PyPIPython 3.8 or higher. (3.7 might work but is not supported)x86_64oraarch64architecture.glibc 2.17 or higher. (released in 2014)pip 19.3 or higher.Starting with version0.8rc2the libsystemd is statically
linked and is not required.Pass--only-binary ':all:'to pip to ensure that it
installs binary package.i686,ppc64leands390xcan be supported if there is a
demand. Please open an issue if you are interested in those
platforms.Source package or compiling from sourcePython 3.8 or higher.Python headers. (python3-devpackage on ubuntu)GCC.libsystemd or libelogindlibsystemd headers. (libsystemd-devpackage on ubuntu)Python setuptools.pkg-configSystemd version should be higher than 246.Optional dependenciesJinja2 for code generator.Sphinx for autodoc.InstallationPyPIURL:https://pypi.org/project/sdbus/pip install --only-binary ':all:' sdbusAURURL:https://aur.archlinux.org/packages/python-sdbus-git/Example codeInterfaceexample_interface.pyfile:fromsdbusimport(DbusInterfaceCommonAsync,dbus_method_async,dbus_property_async,dbus_signal_async)# This is file only contains interface definition for easy import# in server and client filesclassExampleInterface(DbusInterfaceCommonAsync,interface_name='org.example.interface'):@dbus_method_async(input_signature='s',result_signature='s',)asyncdefupper(self,string:str)->str:returnstring.upper()@dbus_property_async(property_signature='s',)defhello_world(self)->str:return'Hello, World!'@dbus_signal_async(signal_signature='i')defclock(self)->int:raiseNotImplementedErrorServerexample_server.pyfile:fromasyncioimportnew_event_loop,sleepfromrandomimportrandintfromtimeimporttimefromexample_interfaceimportExampleInterfacefromsdbusimportrequest_default_bus_name_asyncloop=new_event_loop()export_object=ExampleInterface()asyncdefclock()->None:"""This coroutine will sleep a random time and emita signal with current clock"""whileTrue:awaitsleep(randint(2,7))# Sleep a random timecurrent_time=int(time())# The interface we defined uses integersexport_object.clock.emit(current_time)asyncdefstartup()->None:"""Perform async startup actions"""# Acquire a known name on the bus# Clients will use that name to address this serverawaitrequest_default_bus_name_async('org.example.test')# Export the object to D-Busexport_object.export_to_dbus('/')loop.run_until_complete(startup())task_clock=loop.create_task(clock())loop.run_forever()Clientexample_client.pyfile:fromasyncioimportnew_event_loopfromexample_interfaceimportExampleInterface# Create a new proxied objectexample_object=ExampleInterface.new_proxy('org.example.test','/')asyncdefprint_clock()->None:# Use async for loop to print clock signals we receiveasyncforxinexample_object.clock:print('Got clock: ',x)asyncdefcall_upper()->None:s='test string's_after=awaitexample_object.upper(s)print('Initial string: ',s)print('After call: ',s_after)asyncdefget_hello_world()->None:print('Remote property: ',awaitexample_object.hello_world)loop=new_event_loop()# Always binds your tasks to a variabletask_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()