The Python Oracle

How to get POSTed JSON in Flask?

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Lost Jungle Looping

--

Chapters
00:00 How To Get Posted Json In Flask?
00:33 Accepted Answer Score 631
01:30 Answer 2 Score 95
02:13 Answer 3 Score 210
02:45 Answer 4 Score 36
03:00 Thank you

--

Full question
https://stackoverflow.com/questions/2000...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #json #post #flask

#avk47



ACCEPTED ANSWER

Score 631


First of all, the .json attribute is a property that delegates to the request.get_json() method, which documents why you see None here.

You need to set the request content type to application/json for the .json property and .get_json() method (with no arguments) to work as either will produce None otherwise. See the Flask Request documentation:

The parsed JSON data if mimetype indicates JSON (application/json, see .is_json).

You can tell request.get_json() to skip the content type requirement by passing it the force=True keyword argument.

Note that if an exception is raised at this point (possibly resulting in a 400 Bad Request response), your JSON data is invalid. It is in some way malformed; you may want to check it with a JSON validator.




ANSWER 2

Score 210


For reference, here's complete code for how to send json from a Python client:

import requests
res = requests.post('http://localhost:5000/api/add_message/1234', json={"mytext":"lalala"})
if res.ok:
    print(res.json())

The "json=" input will automatically set the content-type, as discussed here: How to POST JSON data with Python Requests?

And the above client will work with this server-side code:

from flask import Flask, request, jsonify
app = Flask(__name__)

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print(content['mytext'])
    return jsonify({"uuid":uuid})

if __name__ == '__main__':
    app.run(host= '0.0.0.0',debug=True)



ANSWER 3

Score 95


This is the way I would do it and it should be

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.get_json(silent=True)
    # print(content) # Do your processing
    return uuid

With silent=True set, the get_json function will fail silently when trying to retrieve the json body. By default this is set to False. If you are always expecting a json body (not optionally), leave it as silent=False.

Setting force=True will ignore the request.headers.get('Content-Type') == 'application/json' check that flask does for you. By default this is also set to False.

See flask documentation.

I would strongly recommend leaving force=False and make the client send the Content-Type header to make it more explicit.




ANSWER 4

Score 36


Assuming you've posted valid JSON with the application/json content type, request.json will have the parsed JSON data.

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/echo', methods=['POST'])
def hello():
   return jsonify(request.json)