I know its a very basic question but after wasting my whole day I am asking this. I am just sending data using following AngularJS code to Django:
$http.post('/data/creation',
{
html: 'a'
}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log(status);
console.log(data);
});
and in django:
#csrf_exempt
def snippets_post(request):
html = False
css = False
js = False
JSONdata = False
response = "You're looking at the results of question %s."
if request.method == 'POST':
try:
JSONdata = request.POST.get('data', False) # it was [] in actual
except:
JSONdata = 'ERROR'
return HttpResponse(JSONdata)
I am getting False as response, "by replacing data to html in POST.get result is same". I don't know whats going wrong here. Can any one help me here on this?
Thanks
Actually, when we send data from AngularJs using $http's POST, it sends the data with the content-type = "application/json" to the server. And Django doesn't understand that format. And so you can't get the sent data.
Solution is to change the content-type header by using following config:
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
}]);
Related
I am making ajax call to flask function to get data using a token as following
#app.route("/questgen/results", methods = ['POST', 'GET'])
def fetch_results():
token = request.form.get('token')
print(token)
conn = sqlite3.connect("database.db" , timeout=20)
cur= conn.cursor()
select_query = '''SELECT processed, output_text
FROM results
WHERE token = token
'''
cur.execute(select_query)
records = cur.fetchall()
processed = ""
html = ""
for row in records:
processed = row[0]
html = row[1]
conn.close()
data = {'processed': processed, 'html' : html}
return redirect(url_for('questgen', data = data))
ajax call is as following
$.ajax({
type: "POST",
url: "/questgen/results",
data: { token: token },
datatype: "json",
success: function (data) {
if (data.processed == 1) {
$('#divresults').html(data.html);
$('#divresults').show();
hideMyModal();
clearInterval(saveInterval);
}
}
});
the complete is a bit lengthy it can be found in this gist the problem is that it returns
TypeError: The view function did not return a valid response. The
function either returned None or ended without a return statement.
even though I have tried same flask function as python function by using return data on the same database and it works. I have even tried to get token as function parameter but still it's not working. Can someone help with what am I doing wrong here? Thank you
The jQuery ajax call does not handle redirects automatically. You'll just get a response with a 301 or 302 status code. If you really need to have it redirect, you'll need to check for a 302 status return and make the call again with the changed data. It would be better if you could just do the redirection internally by calling the other function.
Try jsonify to return data
from flask import Flask, jsonify, request #import this
And then use this to return data
return jsonify({"res": data})
In ajax you will get your data in res
console.log(data.res) // your data
console.log(data.res.processed) // your if condition
Also check whether you need to parse response body or not
I have test website here. I have already enabled CORS in my code.
app = Flask (__name__,
static_url_path='',
static_folder='./')
cors = CORS(app,
resources={r"/*":{"origins":"*"}},
cors_allowed_origins="*",
async_mode='threading'
)
socketio = SocketIO(app)
socketio.run(app,port=5000, host='0.0.0.0')
This is a sample response:
#app.route('/getobsspecieslist', methods = ['GET'])
##cross_origin(origin='localhost',headers=['Content- Type','Authorization'])
def resp_obsspecieslist():
response = {}
# Check if user sent a name at all
query = """
select t2.COMMONNAME
from bird_observation_location_date_v3 t1
left join ebird_info_dataset t2 on t2.bird_id = t1.bird_id
group by t2.COMMONNAME
order by t2.COMMONNAME asc
"""
resp = []
res = query_db(query)
for row in res:
resp += [{'name': row[0]}]
response["result"] = resp
response = jsonify(response)
response.headers.add('Access-Control-Allow-Origin', '*')
# Return the response in json format
return response
Still, it is not working as intended. I have looked around and tried multiple suggestions to no avail. Please help!
===============================================================
Further examination shows this error comes first:
Error TypeError: NetworkError when attempting to fetch resource. index.js:588:17
SetupSpeciesDropdown http://cocostraws.com/script/index.js:588
(Async: promise callback)
SetupSpeciesDropdown http://cocostraws.com/script/index.js:587
_onload http://cocostraws.com/script/index.js:18
onload http://cocostraws.com/script/index.js:2
(Async: EventHandlerNonNull)
<anonymous> http://cocostraws.com/script/index.js:2
It comes from this chunk of code:
function SetupSpeciesDropdown() {
var url = "http://127.0.0.1:5000/getobsspecieslist"
//var url = "http://www.cocostraws.com/getobsspecieslist"
fetch(url, {mode: 'cors'}).then(res => res.json()).then(function(speciesList) {
d3.select("select#dropdown")
.selectAll('myOptions')
.data(speciesList["result"])
.enter()
.append('option')
.text(function (d) { return d["name"]; }) // text showed in the menu
.attr("value", function (d) { return d["name"]; }); // corresponding value returned by the button
d3.select("select#dropdown").on("change", function(d) {
// recover the option that has been chosen
selectedBird = d3.select(this).property("value");
// run the updateChart function with this selected option
LoadHeatMapData(selectedBird);
});
// Load the map corresponding to the first species in the list.
selectedBird = speciesList["result"][0]["name"];
LoadObsHeatMapData(speciesList["result"][0]["name"]);
})
.catch((error) => {
console.error('Error ', error); /* this is line 588 */
});
};
Line 588 is from the error handling. It fails at the earlier fetch. Could someone point out my error?
The regex in your resource map is incorrect: r"/*" matches a string of zero or more forward slashes, you want r"/.*" instead. flask_cors expects regex syntax (using packgage re), not glob syntax.
But you may have other problems. cors_allowed_origins and async_mode are not documented keyword arguments, and you don't need the line response.headers.add('Access-Control-Allow-Origin', '*'), this should be handled by the extension.
Finally, do you need to be able to pass credentials? If so, look at the documentation of the supports_credentials option... and note that you cannot use it with the origin *, it's just too unsafe.
Found the issue. It is from these two lines:
var url = "http://127.0.0.1:5000/getobsspecieslist"
//var url = "http://www.cocostraws.com/getobsspecieslist"
The problem is that my site does not have www. in front. Changing it to this solves the problem.
var url = "http://cocostraws.com/getobsspecieslist"
I don't know for what you are using CORS header, but if you are doing this for an AJAX request in front-end javascript, using a CORS header will definitely work...See the W3schools documentation for AJAX.
I am trying to write a function in python that returns the json from a request to the smmry API. I was able to get it working with the SM_URL request like this:
def summry():
API_ENDPOINT = "https://api.smmry.com"
API_KEY = "B..."
params = {
"SM_API_KEY":API_KEY,
"SM_URL":"https:..."
}
r = requests.get(url=API_ENDPOINT, params=params)
return r.json()
However, I am not sure how you would do this for passing in a block of text instead of a URL. I have tried making the request with sm_api_input=my_input but that returned an error of insufficient variables. I have also tried it with a POST request and got the same error.
If anyone is curious, this is how I solved the problem. Turns out I needed an Expect: 100-continue header and the sm_api_input is a separate post field instead of a get query.
def summry(text):
API_KEY = "B..."
API_ENDPOINT = "https://api.smmry.com"
data = {
"sm_api_input":text
}
params = {
"SM_API_KEY":API_KEY
}
header_params = {"Expect":"100-continue"}
r = requests.post(url=API_ENDPOINT, params=params, data=data, headers=header_params)
return r.json()
I have a Flask API with this endpoint :
#app.route('/classify/', methods=['POST'])
def classify():
data = request.get_json()
When I POST a request with python, eveything is fine.
But when I use Postman, I get :
<class 'werkzeug.exceptions.BadRequest'> : 400: Bad Request
I send the same Json with both (I copy/paste it to be sure). I am fairly confident the issue is caused by some "\t" in my json, which are escaped by python but not by Postman.
Is there a way to retrieve the raw json, and process it (escape what needs to be escaped) in the app ? Or another way to get the json ?
EDIT : This is a different question from the one you suggested as duplicate, because yours suggest to use get_json, which is the problem in my case.
Ok, so it turns out you can replace :
data = request.get_json()
By :
data = json.loads(request.data, strict=False) # strict = False allow for escaped char
requests.data contains the json in string format, so you can process the characters that needs to be escaped.
use request.data instead of request.get_json() if your data could be empty or a bad request will be raised!
All error about ajax and flask send data from templates for python file.
Recive all data of ajax json.
data = request.get_json("")
print(data)
return "success!"
Send data in ajax json.
$(document).on('click','#texthide',function(){
var text = $("#textVal").val();
var font = $("#font_text").val();
var color = $("#color_text").val();
var start_text = $("#start_text").val();
var end_text = $("#end_text").val();
var vid_id = new_d
console.log(text);
$.ajax({
url: '/videos/test_text',
type: 'POST',
contentType: 'application/json; charset=utf-8',
datatype: "json",
data: JSON.stringify(
{ text: $("#textVal").val(),
font: $("#font_text").val(),
color: $("#color_text").val(),
start_text: $("#start_text").val(),
end_text: $("#end_text").val(),
video_id: new_d
})
});
});
I have confusion on how the servers(here app engine) respond to AJAX GET and POST requests. I want send a GET request to my server and get some JSON data back.
Here is the AJAX GET request
function syncRestoreLinks(e) {
var request = new XMLHttpRequest();
var url = "/sync"
request.open("GET", url);
request.setRequestHeader("Content-Type", "application/json");
request.onreadystatechange = function() {
if (request.readyState === 4) {
console.log(request.responseText);
}
}
request.send(null);
console.log("Getting links from db");
}
Handler on the server side
class SyncHandler(Handler):
def get(self):
response_data = {"loggedIn":False, "linkData":None, "success":False}
json_txt = json.dumps(response_data)
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_txt)
def post(self):
response_data = {"loggedIn":False, "linkData":None, "success":False}
json_txt = json.dumps(response_data)
self.response.headers['Content-Type'] = 'application/json; charset=UTF-8'
self.response.out.write(json_txt)
This handler writes my response data out to the screen where as I want it to send it back and let JS handle it. (I am able to use server redirects here.)
If I make a POST request instead, the code works the way I intend it to. But here, I cannot make server redirects or render pages and only the script making request has that control.
Is this how GET/POST responses work or I am doing something stupid in my code?
Is there any way for GET response not to be written on the page and be sent to JS? In the code above the responseText is an empty string but, the json is printed on screen.
I'm doing AJAX Get requests successfully with app engine right now.
Your sync handler looks correct. Are you sure it is being called? Add a logging.info() statement there to make sure. If it is being called, then I suspect the error is on the front end. I use jQuery and not XMLHttpRequest so I can't you help you with that. My jQuery call looks like this:
$.get(url, callback_function, 'json');
You can add a POST handler to your SyncHandler like this:
def post(self):
...
self.response.out.write(json_txt)
The strange part is that your POST request should not be working without this code to handle the request. You only show a get() method in your code.