Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

json serialisation of dates on flask restful

I have the following resource:

class Image(Resource):
    def get(self, db_name, col_name, image_id):
        col = mongo_client[db_name][col_name]
        image = col.find_one({'_id':ObjectId(image_id)})
        try:
            image['_id'] = str(image['_id'])
        except TypeError:
            return {'image': 'notFound'}
        return {'image':image}

linked to a certain endpoint.

However, image contains certain datetime objects inside. I could wrap this around with `json.dumps(..., default=str), but I see that there is a way of enforcing this on flask-restful. It's just not clear to me what exactly needs to be done.

In particular, I read:

    It is possible to configure how the default Flask-RESTful JSON
    representation will format JSON by providing a RESTFUL_JSON
    attribute on the application configuration. 
    This setting is a dictionary with keys that 
     correspond to the keyword arguments of json.dumps().

class MyConfig(object):
    RESTFUL_JSON = {'separators': (', ', ': '),
                    'indent': 2,
                    'cls': MyCustomEncoder}

But it's not clear to me where exactly this needs to be placed. Tried a few things and it didn't work.

EDIT:

I finally solved with this:

Right after

api = Api(app)

I added:

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            #return int(obj.strftime('%s'))
            return str(obj)
        elif isinstance(obj, datetime.date):
            #return int(obj.strftime('%s'))
            return str(obj)
        return json.JSONEncoder.default(self, obj)


def custom_json_output(data, code, headers=None):
    dumped = json.dumps(data, cls=CustomEncoder)
    resp = make_response(dumped, code)
    resp.headers.extend(headers or {})
    return resp

api = Api(app)
api.representations.update({
    'application/json': custom_json_output
})
like image 251
elelias Avatar asked Jan 18 '17 15:01

elelias


People also ask

How to serialize date in json?

toJSON() calls the object's toISOString() method, which returns a string representing the Date object's value. This method is generally intended to, by default, usefully serialize Date objects during JSON serialization, which can then be deserialized using the Date() constructor or Date. parse() as the reviver of JSON.

How do you serialize data in flask?

If your database table uses classes like UUID , Geometry etc., you will need to define a custom serializer for it. Check out the documentation to see what data types are natively supported by the library. You can specify the list of fields you want to serialize by using the serialize_only field in your model class.

What is Flask restful API?

Flask Restful is an extension for Flask that adds support for building REST APIs in Python using Flask as the back-end. It encourages best practices and is very easy to set up. Flask restful is very easy to pick up if you're already familiar with flask. In flask_restful , the main building block is a resource.


1 Answers

Just cleared this out, you just have to do the following:

app = Flask(__name__)
api = Api(app)
app.config['RESTFUL_JSON'] = {'cls':MyCustomEncoder}

This works both for plain Flask and Flask-RESTful.

NOTES:

1) Apparently the following part of the documentation is not that clear:

It is possible to configure how the default Flask-RESTful JSON representation will format JSON by providing a RESTFUL_JSON attribute on the application configuration. This setting is a dictionary with keys that correspond to the keyword arguments of json.dumps().

class MyConfig(object):
    RESTFUL_JSON = {'separators': (', ', ': '),
                    'indent': 2,
                    'cls': MyCustomEncoder}

2)Apart from the 'cls' argument you can actually overwrite any keyword argument of the json.dumps function.

like image 99
Konstantinos Katsantonis Avatar answered Nov 15 '22 10:11

Konstantinos Katsantonis