This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 6 years ago.
This is what i get
b'{"data": "https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/scher7-om-14.52.47.png"}'
when i print my request data from a flask POST web service.
print(request.data)
But when i do url = request.form.get('data', None)
I get value of url variable None
Why?
Your problem is that you sent the request as follows:
req = requests.post(url, data=json.dumps(payload), headers={'Content-Type': 'application/json'})
When sending json data, you should format the request in requests with the json parameter as follows:
req = requests.post(url, json=payload)
Further, in your flask app, you can access submitted json data via request.json
Because the content type is application/json -- it will not appear in request.form -- Data will appear in request.form when a request is received with an appropriate content type such as multipart/form-data
What's the Content-Type header in your POST request?
As described in its docs: request.form is a dict contains data parsed from POST or PUT form, while request.data contains the incoming request data as string in case it came with a mimetype Flask does not handle.
For the following code:
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask("Test")
#app.route("/ping", methods=['POST'])
def ping():
print "Data: ", request.data
print "Form: ", request.form
return "pong"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7070, debug=False)
Curl with default Content-Type, there's no data in request.data:
curl -X POST -H "Content-Type: a/b" --data 'data=https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png' http://localhost:7070/ping
Output:
* Running on http://0.0.0.0:7070/ (Press CTRL+C to quit)
Data:
Form: ImmutableMultiDict([('data', u'https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png')])
127.0.0.1 - - [20/Oct/2016 21:40:41] "POST /ping HTTP/1.1" 200 -
But curl with a unknown Content-Type header, there's no data in request.form:
curl -X POST -H "Content-Type: a/b" --data 'data=https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png' http://localhost:7070/ping
Output:
Data: data=https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png
Form: ImmutableMultiDict([])
127.0.0.1 - - [20/Oct/2016 21:43:52] "POST /ping HTTP/1.1" 200 -
So if you want your form data in request.form, make sure the Content-Type is the one of those Flask can handle.
Related
This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 1 year ago.
I have 1 small program. I'm sending the request of json via CURL X POST and should get the answer.
The client code is:
curl -XPOST -d'{"animal":"cow", "sound":"moooo", "count": "3"}' 192.168.88.88:5000/test
The server code is:
import json
from flask import Flask, request, jsonify
app = Flask(__name)
#app.route("/test", methods=['POST'])
def json_example():
content = request.get_json(silent=True)
animal = content["animal"]
sound = content["sound"]
count = str(content["count"])
i=0
res=''
while i<int(count):
temp = animal + "says " + sound +"\n"
res = temp +res
i = i + 1
return res
app.run(host='0.0.0.0', port = 5000)
If I'm running the request at postman and indicating that this is json type - then all is OK, but if I'm running it via curl - has an error (None type object isn't subscriptable)
Please advice, how to correct the code at server and indicate, that all responses will be type of json.
Thanks
You have to specify -H "Content-Type: application/json" with the curl request. Alternatively you can use request.form.values if you don't specify header type for the request:
curl -H "Content-Type: application/json" -XPOST -d'{"animal":"cow", "sound":"moooo", "count": "3"}' 192.168.88.88:5000/test
For your curl request the mimetype given by request.mimetype is 'application/x-www-form-urlencoded'
I'm trying yo pass a Content-Type to a flask app (running on GAE), But from python I cannot get the content type header even though I'm passing it
The server-side handler is the following:
#app.route('/api/handlers',methods=['POST'])
def color_list_post():
if(request.headers['Content-Type']=='application/color'):
logging.info('my-format')
elif(request.headers['Content-Type']=='application/x-www-form-urlencoded'):
logging.info('url-encoded')
else:
logging.info('wrong content-type')
return ""
The header passed is:
application/color
this is my request:
curl -H "Content-Type:application/color" -X POST http://localhost:8080/api/handlers
and this the error I get:
KeyError: 'CONTENT_TYPE'
I'm using FLASK API and I want to use POST requests.
I want just to do an example with POST requests that will return something, I keep getting an error message "Method Not Allowed".
I want to give a parameter(e.g query_params = 'name1' ) to search for a user and to return a JSON, actually I don't know where to give this parameter and I don't understand why I'm getting that message.
Here I did a simple route:
#mod_api.route('/show-user', methods=['POST'])
def show_user():
query_params = 'name1'
query = {query_params: 'Myname' }
json_resp = mongo.db.coordinates.find(query)
return Response(response=json_util.dumps(json_resp), status=200, mimetype='application/json')
Any help please?
The likely reason is that you are probably not doing a POST request against the route, which only accepts POST requests. Here is a simplified example with the mongodb details removed to illustrate this.
from flask import Flask
app = Flask(__name__)
#app.route('/show-user', methods=('POST',))
def show_user():
return "name info"
if __name__ == "__main__":
app.run(debug=True)
Now if we do a POST request it works, but if we do A GET request it raises the error you saw:
curl -H "Content-Type: application/json" -X POST -d '{}' http://127.0.0.1:5000/show-user
name info
curl -H "Content-Type: application/json" -X GET http://127.0.0.1:5000/show-user
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>
My understanding is that request.args in Flask contains the URL encoded parameters from a GET request while request.form contains POST data. What I'm having a hard time grasping is why when sending a POST request, trying to access the data with request.form returns a 400 error but when I try to access it with request.args it seems to work fine.
I have tried sending the request with both Postman and curl and the results are identical.
curl -X POST -d {"name":"Joe"} http://127.0.0.1:8080/testpoint --header "Content-Type:application/json"
Code:
#app.route('/testpoint', methods = ['POST'])
def testpoint():
name = request.args.get('name', '')
return jsonify(name = name)
You are POST-ing JSON, neither request.args nor request.form will work.
request.form works only if you POST data with the right content types; form data is either POSTed with the application/x-www-form-urlencoded or multipart/form-data encodings.
When you use application/json, you are no longer POSTing form data. Use request.get_json() to access JSON POST data instead:
#app.route('/testpoint', methods = ['POST'])
def testpoint():
name = request.get_json().get('name', '')
return jsonify(name = name)
As you state, request.args only ever contains values included in the request query string, the optional part of a URL after the ? question mark. Since it’s part of the URL, it is independent from the POST request body.
Your json data in curl is wrong, so Flask does not parse data to form.
Send data like this: '{"name":"Joe"}'
curl -X POST -d '{"name":"Joe"}' http://example.com:8080/testpoint --header "Content-Type:application/json"
just change args for form and it will work
#app.route('/testpoint', methods = ['POST'])
def testpoint():
name = request.form.get('name', '')`enter code here`
return jsonify(name = name)
I'm having a difficulty trying to make a Python REST POST to a webservice running on Glassfish. I have verified that POST works ok using CURL but having no luck with Python.
Here is the CURL request that works ok.
curl -X POST -H "Content-Type: application/json" -d '{"id":1,"lastname":"smith"}'
http://192.168.0.20:8080/field1/resources/com.field1entity.field1
Here is the Python code to make the POST request
import urllib
import httplib2
def call():
http = httplib2.Http()
url = 'http://192.168.0.20:8080/field1/resources/com.field1entity.field1'
params = urllib.urlencode({"id":11111,"lastname":"oojamalip"})
response, content = http.request(url, 'POST', params, headers={'Content-type':'application/json'})
print "lets stop here to have a looksy at the variables"
print content
if __name__ == '__main__':
namesPage = call()
print namesPage
Output from console,
Unexpected character ('l' (code 108)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: org.apache.catalina.connector.CoyoteInputStream#18f494d; line: 1, column: 2]
Hope someone can shed some light on the problem.
thanks
Nick
You are url encoding the prams and then telling the server it is json encoded
import json
params = json.dumps({"id":11111,"lastname":"oojamalip"})
# then
response, content = http.request(url, 'POST', body=params, headers={'Content-type':'application/json'})