JSON data not reaching view pyramid - python

I'm trying to build a page where when the user presses a button a variable which initially is 0 increments with 1. This number is then sent asynchronously to the server by using jQuery AJAX.
What I have so far is:
In my __init__.py file:
def main(global_config, **settings):
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind = engine)
Base.metadata.bind = engine
config = Configurator(settings = settings)
config.include('pyramid_jinja2')
config.add_static_view('static', 'static')
config.add_static_view('scripts', 'scripts')
# Removed the other views
config.add_route("declare_usage", '/user/{user_id}/{address_id}/declare')
config.add_route("declare_usage_json",'/user/{user_id}/{address_id}/declare.json')
config.scan()
My HTML + Jinja2:
#Removed code for simplicity
<div id="button_add">Add</div>
{{val}}
My JS:
$(document).ready(function(){
var room = 0;
jQuery.ajax({type:'POST',
url: '/user/1/5/declare', #I use a direct user ID and a direct address ID as I'm not sure how to send this to JS from Pyramid ... yet :).
data: JSON.stringify(room),
contentType: 'application/json; charset=utf-8'});
$('#button_add').click(function(){
room = room + 1;
});
});
My view code:
#view_config(route_name = 'declare_usage', renderer = 'declara.jinja2')
#view_config(route_name = 'declare_usage_json', renderer = 'json')
def declara_consum(request):
#Removed code for simplicity
val = request.POST.get('room') #I get a "None value in my html" if I change to request.json_body -> I get an error that there is no json to be parsed.
return { 'val' : val }
What happens is that when I open the debugger the POST request is successful with no data and on the page I get 2 options for 'val':
None -> When I use val = request.POST.get('room')
Error ValueError: No JSON object could be decoded -> When I use val = request.json_body
Also, still can't get it to work if in my JS i change url to be /user/1/5/declare.json and/or data to {'room' : room}
Can somebody please point out what I'm doing wrong?

you don't need another route declare_usage_json, just need separate two function like this
#view_config(route_name = 'declare_usage', renderer = 'declara.jinja2')
def declara_consum(request):
# this will response to your jinja2
return { 'val' : val }
#view_config(route_name = 'declare_usage', xhr=True, renderer = 'json')
def declara_consum_ajax(request):
# this will response to your asynchronously request
val = request.POST.get('room')
return { 'val' : val }
when you send a request using ajax, this will goto the second function.
$.ajax({
type: 'POST',
url: '/user/1/5/declare',
data: {'room' : room},
dataType: 'json'
}).done(function(response){
// update your data at html
});

Related

Issue in uploading image for prediction using a MultiPart POST Request

The call is currently happening via a Flutter application which makes a multi-part POST request.
Flutter Code
var request = http.MultipartRequest(
'POST',
Uri.parse('https://techfarmtest.herokuapp.com/upload'),
);
Map<String, String> headers = {"Content-type": "multipart/form-data"};
request.files.add(
http.MultipartFile(
widget.selectedImage.toString(),
widget.selectedImage.readAsBytes().asStream(),
widget.selectedImage.lengthSync(),
filename: widget.selectedImage.path.split('/').last,
),
);
request.headers.addAll(headers);
var res = await request.send();
http.Response response = await http.Response.fromStream(res);
var data = jsonDecode(response.body);
return data;
I intend to upload the image to the backend and then perform the prediction and retrieve the result in JSON format and the backend is scripted using Flask.
Flask Code
#app.route('/upload',methods=["POST"])
def upload_image():
if request.method == "POST":
imageFile = request.files['image']
fileName = werkzeug.utils.secure_filename(imageFile.filename)
print('\nRecieved File name : ' + imageFile.filename)
imageFile.save('./uploadedImages/' + fileName)
pred('./uploadedImages/fileName')
def pred(sampleFile):
model = load_model('./model.h5')
# model.summary()
sample_file = sampleFile
sample_img = image.load_img(sample_file,target_size = (256,256,3))
sample_img = image.img_to_array(sample_img)
sample_img = np.expand_dims(sample_img,axis=0)
prediction_arr = model.predict(sample_img)
result = {
'Sample' : str(sampleFile),
'Label' : str(class_names[prediction_arr.argmax()]),
'Confidence' : str(prediction_arr.max())
}
return jsonify(result)
The current issue I am facing is that I am making a bad request (400).This is a rough code (pseudocode) that I have figured out from various resources. Is there any way to go about it.
So, I figured it out by myself.
I will be attaching the code below for future references.
Flutter Code :
var request = http.MultipartRequest(
'POST',
Uri.parse('https://techfarmtest.herokuapp.com/upload'),
);
request.files.add(
await http.MultipartFile.fromPath('image', img.path),
);
var res = await request.send();
You can verify the POST request by using the below logs :
log('${res.statusCode}', name: 'POST-request-statusCode');
log('${res.reasonPhrase}', name: 'POST-request-status');
With respect to Flask :
#app.route('/upload',methods=["POST","PUT"])
def upload_image():
if request.method == "POST":
imageFile = request.files['image']
***you can perform any operation on the file you have recieved from the request now***
Thank you!

Ajax, Flask route, data appended to URL, server error

I'm using a Flask route to update a MYSQL database and I use an AJAX call to trigger this event. Whenever I run the webpage, I get an internal server error because it appends ?bet=1 to my url [and the is not a defined url]. I don't really get what I have to do to make this not happen and it to just run the normal route as defined in my python file. I've read a lot, but I'm not a programmer [I'm a scientist] and I don't know why this is happening. I think that when I submit the AJAX url it automatically updates the url with the data. Thanks for you help.
Custom.py route that I use with Flask
#custom_code.route('/saveddd', methods=['POST','GET'])
def savdict():
# get form data from ajax
#bet = request.form['bet']
try:
bet = request.form['bet']
db_url = "mysql+pymysql://root:Password!#127.0.0.1:3306/mydatabase"
table_name = 'my_experiment_table'
data_column_name = 'datastring'
# boilerplace sqlalchemy setup
# boilerplace sqlalchemy setup
engine = create_engine(db_url, echo=True)#altered by adding echo
conn=engine.connect()
metadata = MetaData()
metadata.bind = engine
existingtable2 = Table('dictatordecisions', metadata, autoload=True)
#print(existingtable2)
#print ("1")
insort = existingtable2.insert().values(Bet = bet)
#fire = sqlalchemy.sql.expression.insert(existingtable2, values=.5, inline=False, bind=None, prefixes=None, returning=None, return_defaults=False)
conn.execute(insort)
return "cool it worked"
except TemplateNotFound:
abort(404)
AJAX call
function death6(){
//var dictoatorresult = 0
//var selfammount = sliderfoo.value;
if (sliderfoo.value == "") {
alert ("please complete the task")
} else {dictatorchoice = sliderfoo.value;
psiTurk.recordTrialData({'phase':'DictatorGame','status':'submit','choice':dictatorchoice});
psiTurk.recordUnstructuredData('dictatordecision', dictatorchoice);
psiTurk.recordUnstructuredData('dice rolls purchased', purchase);
psiTurk.recordUnstructuredData('race manipulation if 1, plant if 2', condition);
psiTurk.recordUnstructuredData('race answers', RaceAnswers);
psiTurk.saveData();
$.ajax({})
$.ajax({
cache: true,
Type:'POST',
url:'/saveddd',
async: false,
data :{"bet" : dictatorchoice},
//crossDomain: true,
//async: false,
dataType: 'text'
//processData: false,
//beforeSend: function (xhr) {
//xhr.setRequestHeader("x-ajax-call", "no-cache");
})
;
psiTurk.showPage('postquestionnaire.html')
}
//d3.selectAll("input").remove();
//d3.selectAll("input").remove();
//d3.selectAll("div").remove();
}
Button maker
function makeButton2(text, callback){
d3.select("body")
.insert("p")
.insert("p")
d3.select("body")
.insert("button")
.attr("type", "button")
.attr("class", "btn btn-primary btn-lg")
.text(text)
.on("click", function(d){callback();});
}
Sliderfoo defined
var sliderSlide = document.createElement("input");
sliderSlide.setAttribute("type","number");
sliderSlide.setAttribute("fontsize","500px");
sliderSlide.setAttribute("min","0.00");
sliderSlide.setAttribute("max","1.00");
sliderSlide.setAttribute("step","0.01");
//sliderSlide.setAttribute("placeholder","0.50");
sliderSlide.setAttribute("id","sliderfoo");
sliderSlide.setAttribute("style", "font-size:25px")
//sliderSlide.setAttribute("syle","width: 300px");
//sliderSlide.setAttribute("width","400")
?bet=1 means you send it as GET, not POST.
Problem can be bacuse you used Type: 'POST' but it should be method: 'POST'.
You could also use directly $.post() instead of $.ajax()

How to get only json value using jquery from calling an API?

The API returns both JSON and also render the template and when i call $.getJSON it will only return that render template but not JSON value. I have tried this
if request.args['type'] == 'json':
return json.dumps(group)
else:
return render_template("/c.., summary=json.dumps(group))
but it says
bad request
Is there any way I can get that JSON value whenever I need it?
This is my view
#cms.route('/add/asset/<client_id>', methods=["GET"])
#login_required
def asset_add(client_id):
if int(current_user.id_) == int(client_id):
group = {}
group['id'] = []
group['pid'] = []
group['name'] = []
for index in range(len([r.id_ for r in db.session.query(Assetgroup.id_)])):
for asset in (Assetgroup.query.filter_by(parent_id=(index or ''))):
group['id'].append(asset.id_)
group['pid'].append(asset.parent_id)
group['name'].append(asset.name)
if request.args['type'] == 'json':
return json.dumps(group)
else:
return render_template("/cms/asset_add.html", action="/add/asset", asset=None,
client_id=client_id,
types=Type.query.all())
else:
return 'permission denied'
and this is my ajax request
$(document).ready(function () {
$('#group_id').click(function () {
$.getJSON(
'/add/asset/' + {{ client_id }},
function (data) {
$('#group_id').find('option').remove();
var len = data.id.length;
for (var i = 0; i < len; i++) {
var option_item = '<option value="' + data.id[i] + '">' + data.name[i] + "</option>";
$('#group_id').append(option_item);
}
}
);
});
});
You can add parameter in html call to get the json result...
i.e)
const Endpoint = '/add/asset/?'
$.getJSON(Endpoint, {type: 'json'}).done(function(data...)
I believe this is what you are looking for
http://flask.pocoo.org/docs/0.12/api/#flask.Request.is_json
That is a flask method that checks if the request is json
Then you can use jsonify still in flask to return json (you need to import it though)
from flask import jsonify
so your code becomes
if request.is_json:
return jsonify(group)
Hope you find that useful and more elegant
One of the easier ways to debug is just return json alone for a start to see how the response looks in a browser. So you can remove login required (assuming you are not yet in production), do not check if the request is_json, then call the api and see what it returns. So assuming your client id is 1
#cms.route('/add/asset/<client_id>', methods=["GET"])
def asset_add(client_id):
if int(current_user.id_) == int(client_id):
group = {}
group['id'] = []
group['pid'] = []
group['name'] = []
for index in range(len([r.id_ for r in db.session.query(Assetgroup.id_)])):
for asset in (Assetgroup.query.filter_by(parent_id=(index or ''))):
group['id'].append(asset.id_)
group['pid'].append(asset.parent_id)
group['name'].append(asset.name)
return jsonify(group)
Now you can visit http://yoursite.com/add/asset/1 to see your response

Pass arguments to multiple forms with the same request in Django

I am new in django and I have a doubt:
Is possible pass arguments to a several forms.
Scenario:
I have an html table rendered with django-tables2, in the first column I have a drop down button. One item from the drop down button open a bootstrap modal window with 3 diffetent forms(all the forma re modelbased forms).
The arguments are pased with a javascript function, the function take the value from some cells of the html table and send this value as argument.
All this form take the same arguments. I can pass the arguments to one form but I need to pass the arguments to all the forms.
In simple words:
How can I pass arguments to various forms in the same post request?
How I say above I am new with django and I don't know if is possible get this functionality.
UPDATE
my forms: (all the forms have the same code. nonly the name change)
class RecepcionForm(forms.ModelForm):
def __init__(self,*args,**kwargs):
super(RecepcionForm,self).__init__(*args,**kwargs)
self.helper = FormHelper(self)
self.helper.layout.append(Submit('save','Grabar'))
class Meta:
model = DetalleRecepcion
my views:(all the form use a view like this. only the name of the view change
def RecepcionView(request):
idp = request.GET.get('i')
anio = request.GET.get('a')
mes = request.GET.get('m')
if request.method == 'POST':
r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
form = RecepcionForm(request.POST, instance=r)
if form.is_valid():
form.save()
return HttpResponseRedirect('/monitor/')
else:
r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
form = RecepcionForm(instance=r)
return render_to_response('recepcion.html',
{'form':form},
context_instance=RequestContext(request))
I only know how to pass the value to an unique form. I use this fucntion:
<script type="text/javascript">
function param(){
var tbl = document.getElementById("myTable");
var rows = tbl.rows;
var argu = "";
for (var i = 0; i < rows.length; i++){
rows[i].onclick = function(){
idpro = this.cells;
argu = "?i="+idpro[0].innerHTML+"&a="+idpro[1].innerHTML+"&m="+idpro[2].innerHTML;
window.location = "/recepcion/"+argu;
}
}
}
</script>
I know that function is really bad coding, but I have some trouble to redirect toe the template using ajax post request.
I try to use this function but I can never redirect to the form where i send the parameters
<script type="text/javascript">
function param(){
$(function(){
//var http = new XMLHttpRequest();
var tbl = document.getElementById("myTable");
var rows = tbl.rows;
var url = "/recepcion/";
for (var i = 0; i < rows.length; i++){
rows[i].onclick = function(){
idpro = this.cells;
ano = this.cells;
mes1 = this.cells;
$.ajax({
async : false,
type:"GET",
url: "/recepcion/",
datatype: 'json',
data: ({i: idpro[0].innerHTML, a: ano[1].innerHTML, m: mes1[2].innerHTML }),
success: function(){
}
});
}
}
});
return false;
}
</script>
Any idea or advice how can I achieve this functionality.?
Thanks in advance

request through ajax render to a page not working django

After making an ajax request data is being sent successfully to view. But the render function is not working. Render function should render to dashboard.html with data. I have imported all files needed to render. Is it because of an ajax request. Thanks in advance...
My ajax request from template
$("#campaign").click(function () {
alert("hey main")
alert($("#campaign").val());
var id = $("#campaign").val()
$.ajax({
type: "POST",
url: "{% url 'appdata' %}",
data: {
userid: id
}
}).done(function () {
alert("Data Sent: ");
}).fail(function () {
alert("error");
});
/* location.reload()*/
});
My urls.py
url(r'^publisher/appdata/?$', 'appdata', name='appdata'),
My views.py
def appdata(request):
print 'hi i am appdata, fetch me after select id'
print request
userid = request.POST['userid']
# print 'userid: %s'%userid
impressions = Impressions.objects.get(id=userid)
# print 'impressionid: %s'%impressions.id
clicks = Clicks.objects.get(id=userid)
revenues = Revenue.objects.get(id=userid)
ecpm = App.objects.get(id=userid)
member = Member.objects.get(id=userid)
campaigns_id = Campaign.objects.get(id=userid)
# print campaigns_id
# print type(campaigns_id)
apps = App.objects.all()
# print apps
# for i in apps:
# print i.name
# print len(camps)
# dict = {'i':impressions, 'c':clicks, 'r':revenues, 'e':ecpm, 'apps': apps, 'member':member, 'c_id':campaigns_id }
# print dict['i'].impressions
return render(request, 'dashboard.html', {'i':impressions, 'c':clicks, 'r':revenues, 'e':ecpm, 'apps': apps, 'member':member, 'c_id':campaigns_id })

Categories