URL for Flask GET vs POST - python

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.

Related

Flask redirect POST with json content-type

I am trying to write a flask application that lets users select some options on a page, creates json string from them, and passes it to another 'build()' function, which is a flask route.
I should also be able to POST a json directly to build().
To avoid code duplication, I tried redirecting the 'Build' button in my form using code 307 and a json argument.
But I want to be able to pass it just as a curl request would do it with json content-type (option #1 below), so I can access the passed json using requests['json'], instead of requests.args['input']
def gui():
...
elif request.form['submit'] == 'Build':
return redirect(url_for('build', json=session['json']), code=307)
...
def build():
input = request.json #1. curl -H "Content-Type: application/json" --data #input.json http://localhost/build
input = json.loads(request.args['input']) #2. curl -H http://localhost/build?input=%7B"database"%3A...
...
How do I set my redirect, response, header etc. in the gui() 'Build' section ?

Flask - Pass back response of inner request

I looked at some of the similar suggested SO questions, but they weren't quite what I was looking for:
I have a Flask server with a POST route that calls another server. I want Flask to return the response from that request as-is.
import os
import requests
from flask import Flask, request, jsonify, make_response, Response
#app.route('/stuff', methods=['POST'])
def get_stuff():
resp = requests.post(...)
return resp
app.run(host='0.0.0.0', port=9999)
I've tried the following but each returns an error:
return jsonify(resp)
return ( resp.raw.read(), resp.status_code, resp.headers.items() )
return Response(json.dumps(resp), status=resp.status_code, mimetype='application/json')
I just want it to pass back what it got
Flask route functions should only return a string, you need a method to convert it and each of the attempts you made probably fell short in one way or another to do so.
Post the error messages, they may clue in how close you are to accomplishing the rerouting of the post response.

Flask restful - Can't see output from json post

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()

How to bypass preflight check while setting Access-Control-Allow-Origin header?

I have a flask app running on 127.0.0.1:5000 and another website running on 127.0.0.1:8000. The website has js function making a post request to the flask app, trying to post some dictionary data to the flask app. In the js function i'm using ajax:
$.ajax({
url: "http://127.0.0.1:5000/",
method: "POST",
headers: {
'Access-Control-Allow-Origin':'*',},
data: dict,
});
In the flask app:
#app.route('/',methods=['POST'])
def hello_world():
ok = request.get_json()
print(ok['id'])
return '', 200
Initially in the ajax call, i didn't put any headers. But it prompted me "Cross-Origin Request Blocked". Then I add the header and the request apparently turns into an OPTIONS request, which after googling, suggests pre-flight check. How can I avoid the check? Or why does this check returns a 200 code and the actual post request does not get through? Please give me some help! I am stuck on this for hours. Thanks!
(p.s. i have tried installing flask_cors library and applied it in the flask app but it also does not work)
The Access-Control-Allow-Origin header is a response header - you don't pass it in your request (from the website JS) - you pass it in the response from your Flask app.
If you pass it in the request, it does nothing, EXCEPT make the browser send a preflight OPTIONS request, since it's not a basic request header.
So.
Remove the Access-Control-Allow-Origin request header from your JS
Add the Access-Control-Allow-Options: * response header to your Flask app (I'm not sure how you add response headers in Flask)

An example of POST request in Flask API gives "Method Not Allowed"

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>

Categories