30
votes

I have a flask app with the following view:

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(request.json)

However, this only works if the request's content type is set to application/json, otherwise the dict request.json is None.

I know that request.data has the request body as a string, but I don't want to be parsing it to a dict everytime a client forgets to set the request's content-type.

Is there a way to assume that every incoming request's content-type is application/json? All I want is to always have access to a valid request.json dict, even if the client forgets to set the application content-type to json.

2
Am I reading this correctly that you just want to return request data in a response? How can you make sure you get JSON then? - favoretti

2 Answers

57
votes

Use request.get_json() and set force to True:

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(request.get_json(force=True))

From the documentation:

By default this function will only load the json data if the mimetype is application/json but this can be overridden by the force parameter.

Parameters:

  • force – if set to True the mimetype is ignored.

For older Flask versions, < 0.10, if you want to be forgiving and allow for JSON, always, you can do the decode yourself, explicitly:

from flask import json

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(json.loads(request.data))
13
votes

the request object already has a method get_json which can give you the json regardless of the content-type if you execute it with force=True so your code would be something like the following:

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(request.get_json(force=True))

in fact, the flask documentation says that request.get_json should be used instead of request.json: http://flask.pocoo.org/docs/api/?highlight=json#flask.Request.json