Receive JSON in python Bottle - python

I am trying to do a JSON post to my Bottle server.
from bottle import request, route, run
#route('/feedback', method='POST')
def feedback():
data = request.json
print data
run(host='localhost',port=8080)
In the client side, I have
$('#user_feedback').submit(function() {
var feedback = {"id": 1}
$.ajax({
type: "POST",
url: "http://localhost:8080/feedback",
data: feedback
});
return false;
});
I am returning false here because I don't want the page to be redirected.
However, the data I received in my Bottle server is always None when printed out.
Please help. Thank you.

request.json expects the content type of the request to be application/json .
So to make it work, you should set the contentType property of your request to application/json and stringify your data :
$.ajax({
type:"POST",
contentType: "application/json",
url:"/feedback",
data: JSON.stringify(feedback)
});

Related

Django not reading JSON data passed through AJAX post request

I am sending an AJAX POST request using the following code (submitData is a JS Map):
var final_json_data = JSON.stringify(submitData);
$.ajax({
type: 'POST',
url: POST_URL,
data: { 'new-order-details': final_json_data },
dataType: 'json'
});
The view for this AJAX request is :
def post(self,request):
new_order_details = request.body
new_order_details = json.loads(new_order_details)
return render(request,'home.html')
The error showing in python is :
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
What could be the error ?
Thanks for any help !

Unable to receive data from AJAX call [Flask]

What I Am Trying To Do: Receive data from AJAX to Flask. Eventually, I would like to send token data (Which will come from stripe) to the flask side
The Problem: I can't print any data to the console. So I'm assuming data is not being passed through.
I am unable to receive data from my Ajax call. I have been searching for some time now and I haven't found a fix. I've seen multiple different solutions for others but none of them worked for me. I'm am trying to implement a custom Stripe payment flow.
What I plan to do eventually is to pass in all the data I need (in the token) through the 'data' parameter in JSON format. Here are the different sides of code
index.html
var handler = StripeCheckout.configure({
key: 'test_key',
image: 'image_url',
locale: 'auto',
token: function(token) {
$.ajax({
url: '/charge',
data: {
'token': '(data im trying to access/print in app.py)'
},
type: 'POST',
success: function(response) {
console.log(response);
},
error: function(error) {
console.log("ERROR");
console.log(error);
},
dataType: "json",
contentType: "application/json"
});
}
});
app.py
from flask import Flask, request
import json
#app.route('/charge', methods=['POST'])
def charge():
# Grab token information
token = request.form['token']
# The line below never prints to console
print(token)
# This test print statement below never prints to console
print("This print statement never runs")
Nothing prints to the console. I've wasted so much time on this so any leads or pointers would be greatly appreciated!
UPDATES
I did some updates suggested by #Daniel Roseman but nothing at all prints to the console.
Try the following code
In javascript:
var data = {token: token}
$.ajax({
url: '/charge',
data: JSON.stringify(data),
type: 'POST',
success: function (response) {
console.log(response);
},
error: function (error) {
console.log("ERROR");
console.log(error);
},
dataType: "json",
contentType: 'application/json;charset=UTF-8',
});
In controller [charge method]:
from flask import Flask
from flask import render_template, request, jsonify
#app.route('/charge', methods=['POST'])
def charge():
# Grab token information
token = request.json['token']
# This is the expected token from json
print(token)
# This test print statement below now prints to console
print("This print statement now runs surely")
# return JSON
return jsonify(
code=0,
msg="Success"
)
You're not posting JSON.
Instead of accessing request.get_json(), you can just access the individual elements from the request.form dictionary. In this case:
token = request.form['token']

How to receive dictionary in post data python

I'm trying to send array as a parameter to the api which is using python and django framework.
Here's my client side code that is being used to access the api:
$.ajax(
type: 'POST',
url: 'http://example.com/api/users',
data: {user:{name:'Rohit Khatri', age:20, father_name:'S.K'},type:'info'},
complete: function(response) {
console.log(response);
}
);
Here's the view where I'm trying to access the request parameters
def get_users(request):
print(request.POST.get('ids'))
and when I try to access ids parameter, It gives None.
If anyone has faced the same problem, please help me.
You can try getting the list as follows:
request.POST.getlist('ids[]')
Note: You will be better off if you send/receive your data as JSON. You first need to set the Accept and Content-Type headers to application/json while sending the request and then convert the json to python object using json.loads. Example as follows:
Javascript/AJAX
$.ajax(
type: 'POST',
url: 'http://example.com/api/users',
contentType: 'application/json'
data: {ids:[1,2,3,4,5],type:'info'},
complete: function(response) {
console.log(response);
}
);
Django
import json
def get_users(request):
ids = request.POST.get('ids')
if ids:
ids = json.loads(ids)
Update:
In case you need to use more complicated data such as an object (dictionary) using json will be your best bet and it will work pretty similar to the above example.
Javascript/AJAX
$.ajax(
type: 'POST',
url: 'http://example.com/api/users',
contentType: 'application/json'
data: {ids:{"x":"a", "y":"b", "z":"c"}, type:'info'},
complete: function(response) {
console.log(response);
}
);
Django
import json
def get_users(request):
ids = request.POST.get('ids')
if ids:
ids = json.loads(ids)

Ajax: Unable to send Json object to bottle webservice

I am trying to understand how the Ajax call works.
I am sending a Json object to a bottle python webservice as an URL.
$.ajax({
type: "POST",
data: {"jstring": JSON.stringify(output)},
url: "http://localhost:8080/salesvolume" ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
$('#container').highcharts(data);
},
error: function() {
alert("Something is not OK")
},
});
The above snippet is my Ajax Call. output is the Json object that I intend to send to the server.
#app.post('/salesvolume')
def salesvolume(db):
jsonstring = request.forms.get('jstring')
_jsonparams = json.loads(jsonstring)
_studios = _jsonparams.Studios
ret = `Some Json`
return json.loads(ret)
app.run(server='paste', host='localhost', port=8080, debug=True, reloader=True)
And this is my Web Service code snippet.
I get a Status Code: HTTP/1.0 500 Internal Server Error
I have been following the Bottle and Jquery documentations but Im just not able to crack this.
Any help on this will be really greatful.
Consider the following things:
1) In JS, change the url to simply: /salesvolume.
2) In Python, remove the arg - db from the salesvolume function definition. Or else you might get this err (a 500 error):
TypeError: salesvolume() takes exactly 1 argument (0 given)
<myServerIP> - - [30/Jul/2015 13:31:27] "POST /salesvolume HTTP/1.1" 500 1328
3) Check indentation. Python it is! I guess
ret = Some Json and
return json.loads(ret) needs indentation (they should be inside the salesvolume function)
I wrote this similar stuff and it seems to be working:
Python:
from bottle import *
import json, requests
#route('/')
def atHome():
return template('index')
#route('/salesvolume', method="POST")
def salesvolume():
#your processings here...
ret = '{"key":"val"}'
return json.loads(ret)
run(host='0.0.0.0', port=8093, debug=True, reloader=True)
index.tpl and JS:
<html>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<body>
<button onclick=ajaxF()>click</button>
</body>
<script>
function ajaxF(){
$.ajax({
type: "POST",
data: {"jstring": JSON.stringify("blah")},
url: "/salesvolume" ,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
console.log('success');
console.log(data)
},
error: function() {
console.log("Something is not OK");
},
});
}
</script>
</html>
Hope it helps!
The following code worked for me in an app using bottle (sends some data to python and dispatches some data back as JSON from python to js):
js:
$.post('/getData', {myStringInput:dataToSendtoBottle}, function(data){
var myJson = JSON.parse(data) //myOutput is dispatched back to js as JSON
});
python:
#route('/getData', method='POST')
def getData():
myDataReceivedfromJs = request.forms.get('myStringIput')
if myDataReceivedfromJs:
myStringOutput = 'OK'
myOutput = json.dumps(myStringOutput)
return myOutput

how to open a PDF file while returning the file in AJAX request success response

I get 2 dates, start and end date, via AJAX. I process the data b/w those 2 dates, generate a report and then returns an HttpResponse. The PDF report is now saved in my main project directory. Now I get a response back in AJAX. So, now how should I process the response in the success function, sent back from the sever and open a PDF file.
Thanks.
jQuery
$(function() {
$("#report_submit").click(function(){
$.ajax({
type : "POST",
url: "/reports/",
data : { 'start_date' : $("#startDate").val() , 'end_date' : $("#endDate").val() },
success : function(result){
},
error : function(result){
}
});
});
});
Django view code
def generate_report(request):
ctx = {}
if request.is_ajax():
if request.POST.has_key('start_date'):
start_date = datetime.strptime(request.POST[ 'start_date'] , '%m/%d/%Y')
end_date = datetime.strptime(request.POST[ 'end_date'] , '%m/%d/%Y')
......
# PDF GENERATED in MAIN PROJECT DIRECTORY
with open(os.path.join(os.path.dirname(__file__),'../../../../gui','Report.pdf')) as pdf:
response = HttpResponse(pdf.read(), content_type='application/pdf')
response['Content-Disposition'] = 'inline;filename=Report.pdf'
return response # so, now when I send a response back, how should I process it in AJAX success function?
pdf.closed
return render(request, 'generate_report/reports.html', ctx)
Don't try and send it in the Ajax response. Instead, get your view to generate a unique URL for the PDF, then get the JS to redirect the browser to that URL:
view:
return HttpResponse(json.dumps({'url': my_url})
JS:
$.ajax({
type : "POST",
dataType: "json",
url: "/reports/",
data : { 'start_date' : $("#startDate").val() , 'end_date' : $("#endDate").val() },
success : function(result){
var url = result['url'];
window.location = url;
},
The simplest solution would be to call window.open(pdf_url) in "success" callback, where pdf_url is the link to your generated pdf report (which you'll need to pass to response).
This problem has been discussed in the following Question... You might need to go for the jquery plugin for file download and please do not forget to set cookie in the response.
PDF file download through XHR Request
You might need to add a javascript file for the file download and also use the folowing code to generate the request to the server.
$.fileDownload(urlll,{
successCallback: function (url)
{
//success code here
},
failCallback: function (html, url)
{
//error code here
}
});
And on the server side while adding the header etc in the response do the following in response object. i.e.
aResponse.addCookie(cookie);
I hope you can solve the issue and can help others as well.. "Dangling Pointer"

Categories

Resources