Unable to read POSTed application/json data in Flask - python

I have a flask app which has one endpoint as:
#app.route('/restaurant/<restaurant_id>', methods=['GET', 'POST'])
def detail(restaurant_id=None):
if request.method == 'GET':
#something
elif request.method == 'POST':
print jsonify(request.get_json(force=True)) #This doesn't work if I set content type as applicaiton/json
comments = [request.form['comment']] #this works if I set content type as form-data
# something
return Response(json.dumps({
'success': True,
'response': json_docs
}), status=200, content_type='application/json')
For some reason, I'm unable to read the POSTed data when it is posted as a JSON with application/json as the Content-Type. The print command just returns None. How do I read the Json data?

request.get_json() returns JSON, so jsonify should turn it back into JSON. And comments should be request.get_json(force=True). Hope this helps.

Related

Flask API keeps returning 400 error when trying to submit multipart/form-data [duplicate]

I want to be able to get the data sent to my Flask app. I've tried accessing request.data but it is an empty string. How do you access request data?
from flask import request
#app.route('/', methods=['GET', 'POST'])
def parse_request():
data = request.data # data is empty
# need posted data here
The answer to this question led me to ask Get raw POST body in Python Flask regardless of Content-Type header next, which is about getting the raw data rather than the parsed data.
The docs describe the attributes available on the request object (from flask import request) during a request. In most common cases request.data will be empty because it's used as a fallback:
request.data Contains the incoming request data as string in case it came with a mimetype Flask does not handle.
request.args: the key/value pairs in the URL query string
request.form: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn't JSON encoded
request.files: the files in the body, which Flask keeps separate from form. HTML forms must use enctype=multipart/form-data or files will not be uploaded.
request.values: combined args and form, preferring args if keys overlap
request.json: parsed JSON data. The request must have the application/json content type, or use request.get_json(force=True) to ignore the content type.
All of these are MultiDict instances (except for json). You can access values using:
request.form['name']: use indexing if you know the key exists
request.form.get('name'): use get if the key might not exist
request.form.getlist('name'): use getlist if the key is sent multiple times and you want a list of values. get only returns the first value.
For URL query parameters, use request.args.
search = request.args.get("search")
page = request.args.get("page")
For posted form input, use request.form.
email = request.form.get('email')
password = request.form.get('password')
For JSON posted with content type application/json, use request.get_json().
data = request.get_json()
To get the raw data, use request.data. This only works if it couldn't be parsed as form data, otherwise it will be empty and request.form will have the parsed data.
from flask import request
request.data
Here's an example of parsing posted JSON data and echoing it back.
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.route('/foo', methods=['POST'])
def foo():
data = request.json
return jsonify(data)
To post JSON with curl:
curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo
Or to use Postman:
To get the raw post body regardless of the content type, use request.get_data(). If you use request.data, it calls request.get_data(parse_form_data=True), which will populate the request.form MultiDict and leave data empty.
If you post JSON with content type application/json, use request.get_json() to get it in Flask. If the content type is not correct, None is returned. If the data is not JSON, an error is raised.
#app.route("/something", methods=["POST"])
def do_something():
data = request.get_json()
To get request.form as a normal dictionary , use request.form.to_dict(flat=False).
To return JSON data for an API, pass it to jsonify.
This example returns form data as JSON data.
#app.route('/form_to_json', methods=['POST'])
def form_to_json():
data = request.form.to_dict(flat=False)
return jsonify(data)
Here's an example of POST form data with curl, returning as JSON:
$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
"name": "ivanleoncz",
"role": "Software Developer"
}
Use request.get_json() to get posted JSON data.
data = request.get_json()
name = data.get('name', '')
Use request.form to get data when submitting a form with the POST method.
name = request.form.get('name', '')
Use request.args to get data passed in the query string of the URL, like when submitting a form with the GET method.
request.args.get("name", "")
request.form etc. are dict-like, use the get method to get a value with a default if it wasn't passed.
Import request:
from flask import request
URL query parameters:
name = request.args.get("name")
age = request.args.get("age")
Form Input:
name = request.form.get('name')
age = request.form.get('age')
OR (use indexing if you know the key exists, specify the name of input fields)
name = request.form['name']
age = request.form['age']
JSON Data (for content type application/json)
data = request.get_json()
To get JSON posted without the application/json content type, use request.get_json(force=True).
#app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
language = req_data['language']
return 'The language value is: {}'.format(language)
To post JSON with jQuery in JavaScript, use JSON.stringify to dump the data, and set the content type to application/json.
var value_data = [1, 2, 3, 4];
$.ajax({
type: 'POST',
url: '/process',
data: JSON.stringify(value_data),
contentType: 'application/json',
success: function (response_data) {
alert("success");
}
});
Parse it in Flask with request.get_json().
data = request.get_json()
You can get request data from
request.form for form data, this includes form and file data,
request.json and request.get_json for JSON data
request.headers for headers
request.args to get query params
They're all like a dictionary, use request.form['name'] if you know the key exists, or request.form.get('name') if it is optional.
The raw data is passed in to the Flask application from the WSGI server as request.stream. The length of the stream is in the Content-Length header.
length = request.headers["Content-Length"]
data = request.stream.read(length)
It is usually safer to use request.get_data() instead.
Here's an example of posting form data to add a user to a database. Check request.method == "POST" to check if the form was submitted. Use keys from request.form to get the form data. Render an HTML template with a <form> otherwise. The fields in the form should have name attributes that match the keys in request.form.
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route("/user/add", methods=["GET", "POST"])
def add_user():
if request.method == "POST":
user = User(
username=request.form["username"],
email=request.form["email"],
)
db.session.add(user)
db.session.commit()
return redirect(url_for("index"))
return render_template("add_user.html")
<form method="post">
<label for="username">Username</label>
<input type="text" name="username" id="username">
<label for="email">Email</label>
<input type="email" name="email" id="email">
<input type="submit">
</form>
To parse JSON, use request.get_json().
#app.route("/something", methods=["POST"])
def do_something():
result = handle(request.get_json())
return jsonify(data=result)
When writing a Slack bot, which is supposed to send JSON data, I got a payload where the Content-Type was application/x-www-form-urlencoded.
I tried request.get_json() and it didn't work.
#app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
Instead I used request.form to get the form data field that contained JSON, then loaded that.
from flask import json
# app.route('/slack/request_handler', methods=['POST'])
def request_handler():
req_data = json.loads(request.form["payload"])
If the body is recognized as form data, it will be in request.form. If it's JSON, it will be in request.get_json(). Otherwise the raw data will be in request.data. If you're not sure how data will be submitted, you can use an or chain to get the first one with data.
def get_request_data():
return (
request.args
or request.form
or request.get_json(force=True, silent=True)
or request.data
)
request.args contains args parsed from the query string, regardless of what was in the body, so you would remove that from get_request_data() if both it and a body should data at the same time.
If the content type is recognized as form data, request.data will parse that into request.form and return an empty string.
To get the raw data regardless of content type, call request.get_data(). request.data calls get_data(parse_form_data=True), while the default is False if you call it directly.
When posting form data with an HTML form, be sure the input tags have name attributes, otherwise they won't be present in request.form.
#app.route('/', methods=['GET', 'POST'])
def index():
print(request.form)
return """
<form method="post">
<input type="text">
<input type="text" id="txt2">
<input type="text" name="txt3" id="txt3">
<input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])
Only the txt3 input had a name, so it's the only key present in request.form.
#app.route('/addData', methods=['POST'])
def add_data():
data_in = mongo.db.Data
id = request.values.get("id")
name = request.values.get("name")
newuser = {'id' : id, 'name' : name}
if voter.find({'id' : id, 'name' : name}).count() > 0:
return "Data Exists"
else:
data_in.insert(newuser)
return "Data Added"
I just faced the same need. I have to save information in case of any unexpected situation. So, I use the following formula:
Info = "%s/%s/%s" % (request.remote_addr, repr(request), repr(session))
repr(request) will give a string representation of the basic information. You could add user-agent data with:
request.headers.get('User-Agent')
I also save the session continent as it could contain valuable information
request.data
This is great to use but remember that it comes in as a string and will need iterated through.
Try - >
from flask import request
#app.route('/', methods=['GET', 'POST'])
def parse_request():
if request.method == 'POST':
data = request.form.get('data')

Request body returning None in google function [duplicate]

I'm trying to build a simple API using Flask, in which I now want to read some POSTed JSON. I do the POST with the Postman Chrome extension, and the JSON I POST is simply {"text":"lalala"}. I try to read the JSON using the following method:
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
content = request.json
print content
return uuid
On the browser it correctly returns the UUID I put in the GET, but on the console, it just prints out None (where I expect it to print out the {"text":"lalala"}. Does anybody know how I can get the posted JSON from within the Flask method?
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:
This will contain the parsed JSON data if the mimetype indicates JSON (application/json, see is_json()), otherwise it will be None.
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.
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)
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.
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)
For all those whose issue was from the ajax call, here is a full example :
Ajax call : the key here is to use a dict and then JSON.stringify
var dict = {username : "username" , password:"password"};
$.ajax({
type: "POST",
url: "http://127.0.0.1:5000/", //localhost Flask
data : JSON.stringify(dict),
contentType: "application/json",
});
And on server side :
from flask import Flask
from flask import request
import json
app = Flask(__name__)
#app.route("/", methods = ['POST'])
def hello():
print(request.get_json())
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
if __name__ == "__main__":
app.run()
If you use force=True, it will ignore the content type of the request and try to parse the body as JSON regardless.
request.get_json(force=True)
You may note that request.json or request.get_json() works only when the Content-type: application/json has been added in the header of the request. If you are unable to change the client request configuration, so you can get the body as json like this:
data = json.loads(request.data)
To give another approach.
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/service', methods=['POST'])
def service():
data = json.loads(request.data)
text = data.get("text",None)
if text is None:
return jsonify({"message":"text not found"})
else:
return jsonify(data)
if __name__ == '__main__':
app.run(host= '0.0.0.0',debug=True)
The following codes can be used:
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
content = request.json['text']
print content
return uuid
Here is a screenshot of me getting the json data:
You can see that what is returned is a dictionary type of data.
Assuming that you have posted valid JSON,
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
content = request.json
print content['uuid']
# Return data as JSON
return jsonify(content)
Even though all the answers I encounter here are right. There is something that I think it should be done as better practice. Here is how I would write it.
from flask import app, request, Flask, jsonify
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
# Check if the request method is POST
if request.method == 'POST':
# content will return eather parse data as JSON
# Or None incase there is no data
content = request.get_json()
print(content)
# The content could be displayed in html page if serialized as json
return jsonify(content) # Return null if there is content
# if it is only get request then just return uuid
return uuid
{
"uuid":1212121212,
"text":"lalala",
"comment":"",
"signed_on":"2022-11-07 00:03:00"
}
you can sent the above data as json and get it in flask application using request.json
from flask import request, Blueprint,flash,json
#app.route('/api/add_message/<uuid>', methods = ["GET", "POST"])
def testing(uuid):
sync_data = request.json
josn_data = json.dumps(sync_data ,default =str)
return josn_data
Try to set force attribute as True in get_json() method to resolve this issue.
request.get_json(force = True)

Data from Classic ASP app not POSTing to local Flask app [duplicate]

I want to be able to get the data sent to my Flask app. I've tried accessing request.data but it is an empty string. How do you access request data?
from flask import request
#app.route('/', methods=['GET', 'POST'])
def parse_request():
data = request.data # data is empty
# need posted data here
The answer to this question led me to ask Get raw POST body in Python Flask regardless of Content-Type header next, which is about getting the raw data rather than the parsed data.
The docs describe the attributes available on the request object (from flask import request) during a request. In most common cases request.data will be empty because it's used as a fallback:
request.data Contains the incoming request data as string in case it came with a mimetype Flask does not handle.
request.args: the key/value pairs in the URL query string
request.form: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn't JSON encoded
request.files: the files in the body, which Flask keeps separate from form. HTML forms must use enctype=multipart/form-data or files will not be uploaded.
request.values: combined args and form, preferring args if keys overlap
request.json: parsed JSON data. The request must have the application/json content type, or use request.get_json(force=True) to ignore the content type.
All of these are MultiDict instances (except for json). You can access values using:
request.form['name']: use indexing if you know the key exists
request.form.get('name'): use get if the key might not exist
request.form.getlist('name'): use getlist if the key is sent multiple times and you want a list of values. get only returns the first value.
For URL query parameters, use request.args.
search = request.args.get("search")
page = request.args.get("page")
For posted form input, use request.form.
email = request.form.get('email')
password = request.form.get('password')
For JSON posted with content type application/json, use request.get_json().
data = request.get_json()
To get the raw data, use request.data. This only works if it couldn't be parsed as form data, otherwise it will be empty and request.form will have the parsed data.
from flask import request
request.data
Here's an example of parsing posted JSON data and echoing it back.
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.route('/foo', methods=['POST'])
def foo():
data = request.json
return jsonify(data)
To post JSON with curl:
curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo
Or to use Postman:
To get the raw post body regardless of the content type, use request.get_data(). If you use request.data, it calls request.get_data(parse_form_data=True), which will populate the request.form MultiDict and leave data empty.
If you post JSON with content type application/json, use request.get_json() to get it in Flask. If the content type is not correct, None is returned. If the data is not JSON, an error is raised.
#app.route("/something", methods=["POST"])
def do_something():
data = request.get_json()
To get request.form as a normal dictionary , use request.form.to_dict(flat=False).
To return JSON data for an API, pass it to jsonify.
This example returns form data as JSON data.
#app.route('/form_to_json', methods=['POST'])
def form_to_json():
data = request.form.to_dict(flat=False)
return jsonify(data)
Here's an example of POST form data with curl, returning as JSON:
$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
"name": "ivanleoncz",
"role": "Software Developer"
}
Use request.get_json() to get posted JSON data.
data = request.get_json()
name = data.get('name', '')
Use request.form to get data when submitting a form with the POST method.
name = request.form.get('name', '')
Use request.args to get data passed in the query string of the URL, like when submitting a form with the GET method.
request.args.get("name", "")
request.form etc. are dict-like, use the get method to get a value with a default if it wasn't passed.
Import request:
from flask import request
URL query parameters:
name = request.args.get("name")
age = request.args.get("age")
Form Input:
name = request.form.get('name')
age = request.form.get('age')
OR (use indexing if you know the key exists, specify the name of input fields)
name = request.form['name']
age = request.form['age']
JSON Data (for content type application/json)
data = request.get_json()
To get JSON posted without the application/json content type, use request.get_json(force=True).
#app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
language = req_data['language']
return 'The language value is: {}'.format(language)
To post JSON with jQuery in JavaScript, use JSON.stringify to dump the data, and set the content type to application/json.
var value_data = [1, 2, 3, 4];
$.ajax({
type: 'POST',
url: '/process',
data: JSON.stringify(value_data),
contentType: 'application/json',
success: function (response_data) {
alert("success");
}
});
Parse it in Flask with request.get_json().
data = request.get_json()
You can get request data from
request.form for form data, this includes form and file data,
request.json and request.get_json for JSON data
request.headers for headers
request.args to get query params
They're all like a dictionary, use request.form['name'] if you know the key exists, or request.form.get('name') if it is optional.
The raw data is passed in to the Flask application from the WSGI server as request.stream. The length of the stream is in the Content-Length header.
length = request.headers["Content-Length"]
data = request.stream.read(length)
It is usually safer to use request.get_data() instead.
Here's an example of posting form data to add a user to a database. Check request.method == "POST" to check if the form was submitted. Use keys from request.form to get the form data. Render an HTML template with a <form> otherwise. The fields in the form should have name attributes that match the keys in request.form.
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route("/user/add", methods=["GET", "POST"])
def add_user():
if request.method == "POST":
user = User(
username=request.form["username"],
email=request.form["email"],
)
db.session.add(user)
db.session.commit()
return redirect(url_for("index"))
return render_template("add_user.html")
<form method="post">
<label for="username">Username</label>
<input type="text" name="username" id="username">
<label for="email">Email</label>
<input type="email" name="email" id="email">
<input type="submit">
</form>
To parse JSON, use request.get_json().
#app.route("/something", methods=["POST"])
def do_something():
result = handle(request.get_json())
return jsonify(data=result)
When writing a Slack bot, which is supposed to send JSON data, I got a payload where the Content-Type was application/x-www-form-urlencoded.
I tried request.get_json() and it didn't work.
#app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
Instead I used request.form to get the form data field that contained JSON, then loaded that.
from flask import json
# app.route('/slack/request_handler', methods=['POST'])
def request_handler():
req_data = json.loads(request.form["payload"])
If the body is recognized as form data, it will be in request.form. If it's JSON, it will be in request.get_json(). Otherwise the raw data will be in request.data. If you're not sure how data will be submitted, you can use an or chain to get the first one with data.
def get_request_data():
return (
request.args
or request.form
or request.get_json(force=True, silent=True)
or request.data
)
request.args contains args parsed from the query string, regardless of what was in the body, so you would remove that from get_request_data() if both it and a body should data at the same time.
If the content type is recognized as form data, request.data will parse that into request.form and return an empty string.
To get the raw data regardless of content type, call request.get_data(). request.data calls get_data(parse_form_data=True), while the default is False if you call it directly.
When posting form data with an HTML form, be sure the input tags have name attributes, otherwise they won't be present in request.form.
#app.route('/', methods=['GET', 'POST'])
def index():
print(request.form)
return """
<form method="post">
<input type="text">
<input type="text" id="txt2">
<input type="text" name="txt3" id="txt3">
<input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])
Only the txt3 input had a name, so it's the only key present in request.form.
#app.route('/addData', methods=['POST'])
def add_data():
data_in = mongo.db.Data
id = request.values.get("id")
name = request.values.get("name")
newuser = {'id' : id, 'name' : name}
if voter.find({'id' : id, 'name' : name}).count() > 0:
return "Data Exists"
else:
data_in.insert(newuser)
return "Data Added"
I just faced the same need. I have to save information in case of any unexpected situation. So, I use the following formula:
Info = "%s/%s/%s" % (request.remote_addr, repr(request), repr(session))
repr(request) will give a string representation of the basic information. You could add user-agent data with:
request.headers.get('User-Agent')
I also save the session continent as it could contain valuable information
request.data
This is great to use but remember that it comes in as a string and will need iterated through.
Try - >
from flask import request
#app.route('/', methods=['GET', 'POST'])
def parse_request():
if request.method == 'POST':
data = request.form.get('data')

Python-flask extracting values from a POST request to REST API

I am trying to extract values from a JSON payload by POST request:
Question 1:
What is a better way to get the data?
First Way?
#app.route('/login', methods=['POST'])
def login():
if request.method == 'POST':
test = request.data
return test
or Second Way?
#app.route('/login', methods=['POST'])
def login():
if request.method == 'POST':
test = json.loads(request.json)
return test
Question 2:
How do I get a specific value?
Given the json payload is:
{ "test": "hello world" }
I tried doing code below, but does not work.
#way1
return request.data["test"]
#error message: TypeError: string indices must be integers, not str
#way2
test["test"]
#error message: TypeError: expected string or buffer
If you are posting JSON to a flask endpoint you should use:
request.get_json()
A very important API note:
By default this function will return None if the mimetype is not application/json but this can be overridden by the force parameter
Meaning... either make sure the mimetype of the POST is application/json OR be sure to set the force option to true
A good design would put this behind:
request.is_json like this:
#app.route('/post/', methods=['POST'])
def post():
if request.is_json:
data = request.get_json()
return jsonify(data)
else:
return jsonify(status="Request was not JSON")

How to get POSTed JSON in Flask?

I'm trying to build a simple API using Flask, in which I now want to read some POSTed JSON. I do the POST with the Postman Chrome extension, and the JSON I POST is simply {"text":"lalala"}. I try to read the JSON using the following method:
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
content = request.json
print content
return uuid
On the browser it correctly returns the UUID I put in the GET, but on the console, it just prints out None (where I expect it to print out the {"text":"lalala"}. Does anybody know how I can get the posted JSON from within the Flask method?
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:
This will contain the parsed JSON data if the mimetype indicates JSON (application/json, see is_json()), otherwise it will be None.
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.
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)
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.
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)
For all those whose issue was from the ajax call, here is a full example :
Ajax call : the key here is to use a dict and then JSON.stringify
var dict = {username : "username" , password:"password"};
$.ajax({
type: "POST",
url: "http://127.0.0.1:5000/", //localhost Flask
data : JSON.stringify(dict),
contentType: "application/json",
});
And on server side :
from flask import Flask
from flask import request
import json
app = Flask(__name__)
#app.route("/", methods = ['POST'])
def hello():
print(request.get_json())
return json.dumps({'success':True}), 200, {'ContentType':'application/json'}
if __name__ == "__main__":
app.run()
You may note that request.json or request.get_json() works only when the Content-type: application/json has been added in the header of the request. If you are unable to change the client request configuration, so you can get the body as json like this:
data = json.loads(request.data)
If you use force=True, it will ignore the content type of the request and try to parse the body as JSON regardless.
request.get_json(force=True)
To give another approach.
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/service', methods=['POST'])
def service():
data = json.loads(request.data)
text = data.get("text",None)
if text is None:
return jsonify({"message":"text not found"})
else:
return jsonify(data)
if __name__ == '__main__':
app.run(host= '0.0.0.0',debug=True)
The following codes can be used:
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
content = request.json['text']
print content
return uuid
Here is a screenshot of me getting the json data:
You can see that what is returned is a dictionary type of data.
Assuming that you have posted valid JSON,
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
content = request.json
print content['uuid']
# Return data as JSON
return jsonify(content)
Even though all the answers I encounter here are right. There is something that I think it should be done as better practice. Here is how I would write it.
from flask import app, request, Flask, jsonify
#app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
# Check if the request method is POST
if request.method == 'POST':
# content will return eather parse data as JSON
# Or None incase there is no data
content = request.get_json()
print(content)
# The content could be displayed in html page if serialized as json
return jsonify(content) # Return null if there is content
# if it is only get request then just return uuid
return uuid
{
"uuid":1212121212,
"text":"lalala",
"comment":"",
"signed_on":"2022-11-07 00:03:00"
}
you can sent the above data as json and get it in flask application using request.json
from flask import request, Blueprint,flash,json
#app.route('/api/add_message/<uuid>', methods = ["GET", "POST"])
def testing(uuid):
sync_data = request.json
josn_data = json.dumps(sync_data ,default =str)
return josn_data
Try to set force attribute as True in get_json() method to resolve this issue.
request.get_json(force = True)

Categories