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>
Related
I'm using flask to create api server, which get post of json data.
I used following this tutorial to create the code:
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/postjson', methods = ['POST'])
def postJsonHandler():
print (request.is_json)
content = request.get_json()
print (content)
return 'JSON posted'
app.run(host='0.0.0.0')
When I run:
curl -X POST http://127.0.0.1:5000/postjson -H "Content-type: application/json" -d '{ "data": { "url": "https://google.com" }}'
I just see "JSON posted", without any print. Why can't I see any data?
I also tried to use POSTMAN, but same result.
I also tried the json in the example of the guide:
{
"device":"TemperatureSensor",
"value":"20",
"timestamp":"25/01/2017 10:10:05"
}
also the same.
EDIT- as #TomMP answer, when I tried the following code:
from flask import Flask
from flask import request
app = Flask(__name__)
#app.route('/producer', methods = ['POST'])
def postJsonHandler():
print (request.is_json)
content = request.get_json()
print (content)
return request.get_json()
#return 'JSON posted'
app.run(host='0.0.0.0')
I get:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
And When I try the debug mode, I get:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>TypeError: 'dict' object is not callable
The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a dict. // Werkzeug Debugger</title>
<link rel="stylesheet" href="?__debugger__=yes&cmd=resource&f=style.css"
type="text/css">
... (more lines of data)
that because you only return text 'JSON posted'
so return what you want to get
like json response:
return jsonify({'status': 0, 'msg': 'success'})
detail
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.route('/postjson', methods = ['POST'])
def postJsonHandler():
content = request.json
print(content)
return jsonify(content)
app.run(host='0.0.0.0')
call example:
requests.post('http://0.0.0.0:5000/postjson', json={'a':'b'}).json()
When you use print() it simply prints everything to console, so check it for you running app to see printed output. What you return ('JSON posted') from your view is what gets sent back to the client as a response.
When you use curl to access a route, it will only show you what that route returned - in this case, that's JSON posted. It won't show you the print statements that are in between. You could try and run flask in debug mode. That should print out to the console where you're running this app from.
Edit: To be clear, you still won't receive the data you send as an answer to your request, i.e. in Postman. For this, you will have to return the data at the end of your function using return request.get_json()
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 think this must be a really simple question or perhaps I'm overlooking something major, but I'm only getting started and there is something I just can't figure out.
I wrote a simple flask application:
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.route("/")
def index():
return "Index!"
#app.route('/test', methods=['GET', 'POST'])
def test():
if request.method=='GET':
return "OK this is a get method"
elif request.method=='POST':
return "OK this is a post method"
else:
return("ok")
if __name__ == "__main__":
app.run()
When I open the following URL I get the GET method message as expected.
http://localhost:5000/test
But I can't switch it to a POST method.
What URL would I need to enter to see the POST method message?
Whenever you make a direct URL request via browser, it makes a GET call. It is not related to the URL, but the request type value that goes with the request to your server.
In order to make POST request (OR any other type of request) you may use any Rest Client Tool, refer: How do I manually fire HTTP POST requests with Firefox or Chrome?
Personally I use, Postman which comes as plugin for Chrome. Advance Rest Client is also a very nice alternative to achieve this.
If you want a geeky tool (some people consider command line to be geeky ;) ), you may use curl for transferring data with URLs. For making POST request, you have to call it as:
curl -i -X POST -H 'Content-Type: application/json' -d '{"param1": "value1", "param2": "value2"}' http://localhost:5000/test
HTML Forms are the primary way that you'd send a post request. Instead of your return "Index" you could instead do:
return '''
<form method="post" action="/test">
<input type="text" name="your field"/>
<button type="submit">Post to your /test!</button>
</form>
'''
In reality you'd have that form code in a whatever.html file within your template folder and render it with render_template to keep your code smart.
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'})