Send data to Flask backend with Ajax POST request - javascript

Ajax requests are all new to me. I want to send data from a webpage to my Flask backend using an Ajax request but nothing shows up in the backend:
This is my request:
function confirm() {
const xhttp = new XMLHttpRequest();
const data = document.getElementById("tableID");
xhttp.open("POST", "app.py");
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(data);
console.log(xhttp);
console.log(data);
}
In the google chrome console the request and the data are showing up correctly, something like:
<table id="tableID">
<tbody>
<tr>...</tr>
<tr>...</tr>
<tr>...</tr>
</tbody>
</table>
My backend is:
#app.route('/admintools', methods=["POST", "GET"])
def admintools():
tracks = observed_tracks(get_tracks())
if request.method == "POST":
print("request.method == POST")
print(request.form)
if request.method == "GET":
print("request.method == GET")
print(request.form)
return render_template("tools/admintools.html", tracks=tracks)
and nothing shows up in the terminal but:
request.method == GET
ImmutableMultiDict([])
(Not a single time in the html page I say "GET" request)
Do you have any idea what's wrong with it ?

The solution is simple.
Depending on which method is used (POST, GET, PUT, ...), data is submitted different
When using POST for example, data is packed as "Form data" and can be accessed by reading request.form
When sending a GET request though, data is not submitted as "Form data", but as URL arguments instead, which can be accessed by reading request.args
You can obtain more about request data here in the documentation:
https://flask.palletsprojects.com/en/1.1.x/quickstart/#accessing-request-data
Edit: After reading the question again, I just realised the "POST" in your Code.
The request might be interpreted as GET, as the form data is not correctly formatted. The data you are sending must be in a format like field_name=value,...
Check this post for an example:
https://stackoverflow.com/a/9713078

Related

Python Flask get body of Javascript fetch request [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')

Sending A Json object through Fetch API to a Flask Server leads to a 400 Bad Request [duplicate]

This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 2 days ago.
I was trying to send some JSON data to the sever following some online articles and the official flask documentation, but I keep getting a 400 error. What I've tried hasn't worked so far.
I have read that if flask doesn't get properly formated JSON data it pushes this error and also that the read of the request must specify Content-Type header as application/json or else the same happens.
I copied some of my code off the official Documentation and this is what i have so far:
a view function inside my flask application:
#main.route('/test', methods=['GET','POST'])
def test():
if request.method == 'POST':
print(request.method)
print(request.headers.get('Content-Type'))
print(request.is_json)
#this gets me the 400 when run
#print(request.json)
return render_template('test.html')
the following scrip tag inside test.html:
<script>
let data = {"data": "Hello World!"}
document.querySelector('#main').addEventListener('click', function () {
fetch('/test', {
method: "POST",
body: JSON.stringify(data),
headers: {"Content-Type": "application/json"},
credentials: "same-origin"
})
.then(response => console.log(response.json))
})
</script>
Every time I hit the button to POST the data I get the following showing in my terminal
POST
text/plain;charset=UTF-8
False
So I assume what is causing all of this is that the Content-Type header of the HTTP request is not setting properly.
Any ideas on how I could fix this would be apreciated
Based on your code and the error message you are receiving, the issue might be related to the request header not being set correctly.
You are setting the Content-Type header in your JavaScript code to "application/json", which is correct. However, your Flask view function does not check the Content-Type header correctly. You can check it like this:
if request.is_json:
data = request.get_json()
print(data)
else:
print("Request is not JSON")
This checks whether the request is in JSON format using the is_json property of the request object. If it is, then you can use the get_json() method to extract the data. If it's not, you can print a message or return an error.
Additionally, you might want to add a try-except block to catch any errors that might occur when parsing the JSON data:
if request.is_json:
try:
data = request.get_json()
print(data)
except Exception as e:
print("Error parsing JSON data:", e)
return "Bad Request", 400
else:
print("Request is not JSON")
return "Bad Request", 400
This will catch any exceptions when parsing the JSON data and return a "Bad Request" error with a 400 status code.
I hope this helps!
You need to specify the full endpoint of what you are targeting.
from flask import Flask, request
# create the flask app
app = Flask(__name__)
# post endpoint
#app.route('/post', methods=['POST'])
def endpoint():
data = request.get_json()
return data
# run the app
if __name__ == '__main__':
app.run(debug=True)
const endpoint = "http://127.0.0.1:5000/post";
// post request to endpoint
const response = fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "John Doe",
})
});
response.then(data => {
data.text().then(text => {
console.log(text);
})
})

passing ajax data to python flask [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')

How to write data to iframe via Flask POST method

I have an old application based on Python SimpleHTTPServer that I'm trying to convert to Flask.
In the old application, I had an HTML form that was submitting a POST request to the SimpleHTTPServer. The form also had an iframe. There, I had a do_POST method that was reading the values in the text boxes and producing some results. I then wrapped the results into a JSON object and wrote to the wfile method of SIMPLEHTTPServer. This caused the result to get populated into the iframe. The iframe had an onload method on the JS side and here, the results would be read from it and populated into various text-boxes.
I now want to convert this to Flask from SimpleHTTPServer. What is the best way to translate the logic I have in place to Flask? Basically, what is the equivalent of writing to the wfile object?
Also, on the Flask side, I also have some #app.route methods where I can form a URL with input parameters and get the results as JSON objects (example: http://localhost/calculate?input1=3&input2=5). Is it possible to leverage these URLs instead of the POST request to get the result into JavaScript?
Here is hello world of flask to get the data from URL parameters and do the stuff and return a json
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/')
def hello_world():
param1 = request.args.get('param1')
param2 = request.args.get('param2')
res = param1 + param2
return jsonify({
"result": res
})
if __name__ == '__main__':
app.run()
example request
GET http://127.0.0.1:5000/?param1=hi&param2=there
Example response
{
"result": "hithere"
}

Sending image via HTTP form-data to Flask [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')

Categories

Resources