Search code examples
pythonjsonrosbridge

AttributeError: 'module' object has no attribute 'dumps'


For a project I use a ROS-MQTT bridge in Python. This is a library obtained from the ROS Wiki. The library can be found here: https://github.com/groove-x/mqtt_bridge

One of the python files (app.py) uses the following lines of code:

# load serializer and deserializer
  serializer = params.get ('serializer', 'json: dumps')
  deserializer = params.get ('deserializer', 'json: loads')

When running the roslaunch command to start the program, I get the following error referring to the above code: AttributeError: 'module' object has no attribute 'dumps'.

I have looked at this question, but the answers are not helping my situation. I can't find a json.py file anywhere, so I can't rename it either. If I do find sudo. -print | grep -i '. * [.] py' I only get the following files:

./app.py
./__init__.py
./bridge.py
./util.py
./mqtt_client.py

For those interested, the traceback:

Traceback (most recent call last):
  File "/opt/ros/melodic/lib/mqtt_bridge/mqtt_bridge_node.py", line 9, in <module>
    mqtt_bridge_node ()
  File "/opt/ros/melodic/lib/python2.7/dist-packages/mqtt_bridge/app.py", line 50, in mqtt_bridge_node
    mqtt_client, serializer, deserializer, mqtt_private_path)
  File "/opt/ros/melodic/lib/python2.7/dist-packages/mqtt_bridge/app.py", line 15, in create_config
    serializer = lookup_object (serializer)
  File "/opt/ros/melodic/lib/python2.7/dist-packages/mqtt_bridge/util.py", line 12, in lookup_object
    obj = getattr (module, obj_name)
AttributeError: 'module' object has no attribute 'dumps'

For the people interested in the full app.py file:

# -*- coding: utf-8 -*-
from __future__ import absolute_import

import inject
import paho.mqtt.client as mqtt
import rospy

from .bridge import create_bridge
from .mqtt_client import create_private_path_extractor
from .util import lookup_object

def create_config(mqtt_client, serializer, deserializer, mqtt_private_path):
    if isinstance(serializer, basestring):
        serializer = lookup_object(serializer)
    if isinstance(deserializer, basestring):
        deserializer = lookup_object(deserializer)
    private_path_extractor = create_private_path_extractor(mqtt_private_path)
    def config(binder):
        binder.bind('serializer', serializer)
        binder.bind('deserializer', deserializer)
        binder.bind(mqtt.Client, mqtt_client)
        binder.bind('mqtt_private_path_extractor', private_path_extractor)
    return config


def mqtt_bridge_node():
    # init node
    rospy.init_node('mqtt_bridge_node')

    # load parameters
    params = rospy.get_param("~", {})
    mqtt_params = params.pop("mqtt", {})
    conn_params = mqtt_params.pop("connection")
    mqtt_private_path = mqtt_params.pop("private_path", "")
    bridge_params = params.get("bridge", [])

    # create mqtt client
    mqtt_client_factory_name = rospy.get_param(
        "~mqtt_client_factory", ".mqtt_client:default_mqtt_client_factory")
    mqtt_client_factory = lookup_object(mqtt_client_factory_name)
    mqtt_client = mqtt_client_factory(mqtt_params)

    # load serializer and deserializer
    serializer = params.get('serializer', 'json:dumps')
    deserializer = params.get('deserializer', 'json:loads')

    # dependency injection
    config = create_config(
        mqtt_client, serializer, deserializer, mqtt_private_path)
    inject.configure(config)

    # configure and connect to MQTT broker
    mqtt_client.on_connect = _on_connect
    mqtt_client.on_disconnect = _on_disconnect
    mqtt_client.connect(**conn_params)

    # configure bridges
    bridges = []
    for bridge_args in bridge_params:
        bridges.append(create_bridge(**bridge_args))

    # start MQTT loop
    mqtt_client.loop_start()

    # register shutdown callback and spin
    rospy.on_shutdown(mqtt_client.disconnect)
    rospy.on_shutdown(mqtt_client.loop_stop)
    rospy.spin()


def _on_connect(client, userdata, flags, response_code):
    rospy.loginfo('MQTT connected')


def _on_disconnect(client, userdata, response_code):
    rospy.loginfo('MQTT disconnected')


__all__ = ['mqtt_bridge_node']

Does anybody know what the issue could be?


Solution

  • After 5 hours of trying and researching I figured out that one of the packages dependencies was missing. The package was checking for missing dependencies, except for that one.

    By adding some prints in additional files I figured out that it wasn't json that was missing. It was a dependency called msgpack.

    After executing pip install msgpack-python==0.4.8 I could succesfully run the code.