altdesktop / python-dbus-next

🚌 The next great DBus library for Python with asyncio support
https://python-dbus-next.readthedocs.io/en/latest/
MIT License
191 stars 59 forks source link

Add a function to remove all dbus types #21

Open nicola-lunghi opened 4 years ago

nicola-lunghi commented 4 years ago

Hi,

I need to encode the result of a dbus message with json. How can I make the dbus object type serializable? for now I am doing (from your example client)

def jsonify_results(result):
    def conv_default(o):
        """handle the variant type for json.dumps"""
        if type(o) is Variant:
            return o.value
        else:
            raise json.JSONDecodeError()

    assert isinstance(result, Message)
    assert result.message_type is MessageType.METHOD_RETURN
    return json.dumps(result.body, default=conv_default)

There's a better way to get a serializable body without all the dbus types?

Thanks Nick

acrisci commented 4 years ago

That's the way to do it right now. I believe the only nonserializable type is the Variant. I would like to put a function that turns the result into a plain object because I think that's a common use case. I have implemented this in the test suite somewhere. I can probably just put that into the library.

michallowasrzechonek-silvair commented 4 years ago

FWIW, json.dumps takes cls argument, allowing usage of a custom encoder. Maybe it's worth including such an encoder in the library.

nicola-lunghi commented 4 years ago

Something similar to this?

import json
from dbus_next import Variant

class DBusEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Variant):
            return obj.value
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)

json.dumps(data, cls=DBusEncoder)
tzahari commented 2 years ago

It would be nice to have this in the dbus-next library.