3

Is it possible, in a simple way, to make jsonify format floats to one decimal point?

Here is a simple example. How can I add custom json encoder to this:

from flask import Flask, jsonify
from flask.ext.restful import Api, Resource

app = Flask(__name__)
api = Api(app)

class Test(Resource):
    def get(self):
        return jsonify({'data': [.444, .456]});

api.add_resource(Test, '/')

if __name__ == '__main__':
    app.run()

So that the output would be:

{
  "data": [
    0.4, 
    0.5
  ]
}
Helgi Borg
  • 835
  • 10
  • 32
  • Process the data first like so: float(.444) and have a look at this answer: http://stackoverflow.com/questions/4518641/how-to-round-off-a-floating-number-in-python – Maarten Aug 20 '15 at 12:24
  • 1
    @Maarten the data is already a float literal, how does that help? – jonrsharpe Aug 20 '15 at 12:26
  • 1
    Yes in this simple example, the obvious way is to format the data beforehand. In real live, I'm implementing json formatted rest-service that fetches all sorts of data from database. It would be simpler and cleaner to have custom json-encoder handling the json formatting. – Helgi Borg Aug 20 '15 at 13:50

1 Answers1

2

If this is just about rounding floats you can check this answer: how to round off a floating number in python

And for writing custom JSON Encoder this snippet: Custom Flask JSONEncoder

The flask source JSON library here

EDIT: The question here remains what you want to do with what type of data, also when you want to do it. In some cases you might not want to apply any changes to it at all. You have the option to first check the type and then determine what to do with the data before passing it to the encoder or put all that logic into the custom encoder class itself.

Small example:

import json
import math

from flask.json import dumps, JSONEncoder


def round_float(data):
    if type(data) is float:
        rounded = math.ceil(data*100)/100
        return rounded
    else:
        raise TypeError('data must be a float not %s' %type(data))


class CustomJSONEncoder(JSONEncoder):
    def default(self, o):
        #alternatively do the type checking in the default method
        if type(o) is float:
            return round_float(o)
        if type(o) is int:
            return float(o)

encoder = CustomJSONEncoder()

data = dict(floated=encoder.default(2))
data2 = dict(rounded=encoder.default(0.896))

dumps(data)
dumps(data2)

will output:

{"floated": 2.0}
{"rounded": 0.9}
Community
  • 1
  • 1
Maarten
  • 492
  • 7
  • 14
  • Yes in this simple example, the obvious way is to format the data beforehand. In real live, I'm implementing json formatted rest-service that fetches all sorts of data from database. It would be simpler and cleaner to have custom json-encoder handling the json formatting. – Helgi Borg Aug 20 '15 at 13:51
  • In that case it depends if your floats always need to be rounded and if you are expecting any non-numerical data to pass through the encoder. The answer above simply addresses your example. Could you elaborate a bit? – Maarten Aug 20 '15 at 13:55
  • Thanks for your reply Maarten. I'm using this for meteorological and geology data. The data will include strings, time stamps, integers and floats. In some cases the floats need to be formatted to one decimal point, in other cases to whole integers, and yet another cases to more decimal points. – Helgi Borg Aug 20 '15 at 14:25