28

I want to pass a numpy JSON serializer I wrote into Flask's jsonify function, but I cannot find a way to do this. I cannot use json.dumps, because I have to set the status_code of the Flask response when handling an error message. Is there a way to pass the JSON serializer in as a parameter, similar to using the cls parameter in json.dumps as shown here: Convert numpy type to python? My code is below; thanks.

import json
import numpy as np
from flask import Flask, jsonify

class JSON_Improved(json.JSONEncoder):
    '''
    Used to help jsonify numpy arrays or lists that contain numpy data types.
    '''
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        else:
            return super(MyEncoder, self).default(obj)

app = Flask(__name__)
@app.errorhandler(ErrorMessage)
def handle_invalid_usage(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response

3 Answers 3

30

You can custom the json encoder of Flask app with app.json_encoder = JSON_Improved. JSON_Improved inherit from flask.json.JSONEncoder

class JSON_Improved(JSONEncoder):

    pass

There is a Flask Snippets about it in https://web.archive.org/web/20190128005233/http://flask.pocoo.org/snippets/119

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, that's very useful!
The link to the snippet is dead because all snippets were removed from the flask website. See this issue on their website repo. You can get to this snippet at web.archive.org/web/20190128005233/http://flask.pocoo.org/…
Good answer but out of date! app.json_encoder no longer exists! Check below
21

Since json_encoder got deprecated in Flask 2.2 and would be removed in Flask 2.3, the following update might be useful.

The documentation states that:

To use a different provider, either subclass Flask and set json_provider_class to a provider class, or set app.json to an instance of the class.

So, in the case of derived class, the solution would be:

class MyFlask(Flask):
    json_provider_class = CustomJSONProvider

app = MyFlask(__name__)

or, in the case of instantiating class Flask directly, just:

app = Flask(__name__)
app.json = CustomJSONProvider(app)

Given the already defined JSON_Improved encoder, sample class CustomJSONProvider would be:

from flask.json.provider import JSONProvider
    
    
class CustomJSONProvider(JSONProvider):
    
    def dumps(self, obj, **kwargs):
        return json.dumps(obj, **kwargs, cls=JSON_Improved)
    
    def loads(self, s: str | bytes, **kwargs):
        return json.loads(s, **kwargs)

2 Comments

I used your approach and one deprecation warning disappeared, but the log still says: 'JSONEncoder' is deprecated and will be removed in Flask 2.3. Use 'Flask.json' to provide an alternate JSON implementation instead. Makes sense since the JSON_Improved class still inherits from JSONEncoder.
I suggest that JSONEncoder should be imported directly from json module, not the flask.json.
1
For connexion implementation:
...
from flask.json import JSONEncoder
from flask.json.provider import JSONProvider
import json
...

...from Dmitry
class CustomJSONProvider(JSONProvider):

    def dumps(self, obj, **kwargs):
        return json.dumps(obj, **kwargs, cls=JSON_Improved)

    def loads(self, s: str | bytes, **kwargs):
        return json.loads(s, **kwargs)

...
    app = connexion.App(__name__, specification_dir='.//')
    app.app.json = CustomJSONProvider(app.app)

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.