Reputation: 7251
Using ubuntu 20.10
I want to write a python script to process the output of this shell command:
dbus-send --print-reply --dest=org.gnome.SessionManager /org/gnome/SessionManager org.gnome.SessionManager.GetInhibitors
I don't know anything about coding dbus. The first place to start was I hoped a good python library.
I learn this about the apparently canonical library: "dbus-python is a legacy API, built with a deprecated dbus-glib library, and involving a lot of type-guessing (despite "explicit is better than implicit" and "resist the temptation to guess") (from https://wiki.python.org/moin/DbusExamples)
The library https://pypi.org/project/dbus-next/ promises a pure python implementation: "Zero dependencies and pure Python 3." It is not mentioned on the wiki page mentioned above, but it looks like a healthy project. However it seems that the pure python approach requires me to use the asyncio version. I think this is overkill for my needs.
I tried using dasbus but I can't install the necessary libraries, at least not in a virtual env. Despite installing the system package python3-gi, I get errors "no module named gi" and trying to install PyGObject fails because "no package 'cairo' found" ... and ERROR: failed building wheel for pycairo.
So at this point, I have a library which is old and not recommended, a library with dependency difficulties and a library which seems to force me to use asyncio.
I now understand why the php script I am trying to re-write in python executed a shell command and dealt with the ugly output.
On top of that, I think I have worked out these points:
I need the SessionBus
The "path" is "/org/gnome/SessionManager" The "interface" is org.gnome.SessionManager I want to "call" the "member" GetInhibitors
I find async a bit of overkill since this is a shell script but if this is only way I can avoid a C dependency, I will deal with it.
Which library should I use?
Upvotes: 4
Views: 4403
Reputation: 34018
First, how to do what you wanted with two popular easy-to-install python-only MIT licenced packages
Here's how you could use jeepney for the task:
from jeepney import DBusAddress, new_method_call
from jeepney.io.blocking import open_dbus_connection
proxy = DBusAddress('/org/gnome/SessionManager',
bus_name='org.gnome.SessionManager',
interface='org.gnome.SessionManager')
connection = open_dbus_connection(bus='SESSION')
msg = new_method_call(proxy, 'GetInhibitors')
reply = connection.send_and_get_reply(msg)
print(reply.body[0])
And here is how the same could be done in dbus-next. I'm not an expert on the asyncio stuff, but this seems to work even if your code is non-async (synchronous):
import asyncio
from dbus_next.aio import MessageBus
from dbus_next.message import Message
async def main():
bus = await MessageBus().connect()
msg = Message(destination='org.gnome.SessionManager',
path='/org/gnome/SessionManager',
interface='org.gnome.SessionManager',
member='GetInhibitors')
return await bus.call(msg)
reply = asyncio.run(main())
print(reply.body[0])
There are plenty of options. Some of them are easy to install, and some are not.
I tested installability by running python -m pip install <packagename>
inside a fresh virtual environment, inside a fresh Ubuntu 22.04 installation. These packages did not install (as they have additional dependencies):
gi
). Installs, but raises Exceptions on runtime for missing gi
module.gi
module.libdbus-1.so.3
(and it requires that to be available on the system). This shared library is basically part of every system running dbus-daemon (and using dbus). Some dislike libdbus (threading problems? at least the Internet says so). LGPL-2.1 licenced.libsystemd.so.0
on the system. That should be available in any system running systemd (which makes most of the popular distros). LGPL-2.1 licenced.Out of these, current days the
and pysdbus is not listed in PyPI. So jeepney really seems to be most popular choice, perhaps because of easy installation. It is not optimized for speed, though. Having said that, the above code examples, when ran multiple times, take roughly 2 ms with jeepney and 3 ms with dbus-next.
jeepney
, dbus
(python-dbus) and gi
(PyGObject) installed. That does not help with virtual environments, or projects that are supposed to be installed as dependencies (inside venv), though.Upvotes: 6