Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert all Decimals in a Python data structure to string?

I'm building a website using Flask from which I use the jsonify method a lot to convert mostly dictionaries to Json.

The problem is now that I also use Decimals a lot, and unfortunately jsonify cannot handle Decimals:

jsonify({'a': Decimal('1')})

leads to:

=== (a long stacktrace preceding this) ===
File "/usr/local/lib/python2.7/dist-packages/flask/json.py", line 83, in default
return _json.JSONEncoder.default(self, o)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('1') is not JSON serializable

So I wanted to wrap jsonify in a method like this:

def myOwnJsonify(item):
    if isinstance(item, Decimal):
        return flask.jsonify(str(item))
    else:
        return flask.jsonify(item)

unfortunately, this doesn't convert Decimals which reside within a dict or list.

How can I convert all Decimal numbers within a python data structure (be it a list, a dict, a tuple, etc.) into a string so that I can safely convert the datastructure into json?

like image 854
kramer65 Avatar asked Jul 11 '14 21:07

kramer65


1 Answers

You can override the application's JSON encoder by setting the json_encoder attribute on your application instance:

import flask

app = flask.Flask(...)
app.json_encoder = MyJSONEncoder

Then you can sub-class Flask's JSONEncoder and override the default() method to provide support for additional types:

import decimal
import flask.json

class MyJSONEncoder(flask.json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            # Convert decimal instances to strings.
            return str(obj)
        return super(MyJSONEncoder, self).default(obj)
like image 142
Uyghur Lives Matter Avatar answered Oct 05 '22 14:10

Uyghur Lives Matter