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
})
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With