342

I am not sure I understand the purpose of the flask.jsonify method. I try to make a JSON string from this:

data = {"id": str(album.id), "title": album.title}

but what I get with json.dumps differs from what I get with flask.jsonify.

json.dumps(data): [{"id": "4ea856fd6506ae0db42702dd", "title": "Business"}]
flask.jsonify(data): {"id":…, "title":…}

Obviously I need to get a result that looks more like what json.dumps returns. What am I doing wrong?

ballade4op52
  • 2,142
  • 5
  • 27
  • 42
Sergei Basharov
  • 51,276
  • 73
  • 200
  • 335

5 Answers5

446

The jsonify() function in flask returns a flask.Response() object that already has the appropriate content-type header 'application/json' for use with json responses. Whereas, the json.dumps() method will just return an encoded string, which would require manually adding the MIME type header.

See more about the jsonify() function here for full reference.

Edit: Also, I've noticed that jsonify() handles kwargs or dictionaries, while json.dumps() additionally supports lists and others.

HackDolphin
  • 166
  • 11
Kenneth Wilke
  • 4,631
  • 1
  • 15
  • 7
  • 39
    `jsonify()` handles lists now. See [this commit](https://github.com/mitsuhiko/flask/commit/431db2874b242316051963d9bc4d5653b3647acc). – Jeff Widman Jan 25 '16 at 19:14
  • 4
    But it still does not turn SQLAlchemy objects and lists into JSON. – ajbraus Oct 12 '19 at 23:14
  • I used jsonify to send json to the client. While for smaller dictionaries, the response works fine, for large arrays I get a content length mismatched error on the browser. Any ideas as to why this happens? there's a limit to how much data I can send? – sakib11 Aug 10 '20 at 10:47
  • Also, from my test, jsonify handles python's set objects – Raghuram Krishnaswami Mar 19 '22 at 07:54
99

You can do:

flask.jsonify(**data)

or

flask.jsonify(id=str(album.id), title=album.title)
mikerobi
  • 20,527
  • 5
  • 46
  • 42
90

This is flask.jsonify()

def jsonify(*args, **kwargs):
    if __debug__:
        _assert_have_json()
    return current_app.response_class(json.dumps(dict(*args, **kwargs),
        indent=None if request.is_xhr else 2), mimetype='application/json')

The json module used is either simplejson or json in that order. current_app is a reference to the Flask() object i.e. your application. response_class() is a reference to the Response() class.

user
  • 5,335
  • 7
  • 47
  • 63
Michael Ekoka
  • 19,050
  • 12
  • 78
  • 79
  • This is the best answer so far. I think Jsonify is a good shorthand for when no customization of real import is required – Max Sep 11 '22 at 06:16
52

The choice of one or another depends on what you intend to do. From what I do understand:

  • jsonify would be useful when you are building an API someone would query and expect json in return. E.g: The REST github API could use this method to answer your request.

  • dumps, is more about formating data/python object into json and work on it inside your application. For instance, I need to pass an object to my representation layer where some javascript will display graph. You'll feed javascript with the Json generated by dumps.

chaiyachaiya
  • 2,617
  • 18
  • 19
  • 4
    I don't understand the difference at all. – vidstige Nov 18 '15 at 09:59
  • 13
    @vidstige: **jsonify** makes a flask.Response() object with its headers set as "content-type: application/json", its payload set as the converted-to-JSON-string dict. **dumps** simply makes a converted-to-JSON-string. It's not a properly-formatted flask.Response() object. So if your view says "return json.dumps(dict)", then the recipient will just get a regular "content-type:text/html" response with the json.dumps output as the payload. – Sam Aug 19 '16 at 22:11
  • 7
    @SamEsla yes, I know, but none of that information is in this answer. – vidstige Apr 03 '18 at 02:42
-3

consider

data={'fld':'hello'}

now

jsonify(data)

will yield {'fld':'hello'} and

json.dumps(data)

gives

"<html><body><p>{'fld':'hello'}</p></body></html>"