multiple submission buttons to python flask app - python

I am having a problem getting both of these submissions to work. I will search with one and it will be successful then when I refresh and try to search with the other one I get a url not found error. Been fighting with this all day thank you for your help
<playlist>
<input id = "url2" type = "text" name = "url"
placeholder = "Genre">
<input type = "submit" name = "button" onclick =
"test()">.
<script>
function test() {
var url2= document.getElementById("url2").value;
document.write("Generating Playlist");
setTimeout(function(){window.location=
"http://127.0.0.1:5000/recommend/genre/"+url2;}, 3000);
}
</script>
Sorry I'm new to this I didn't realize I wasn't allowed to post screenshots yet. I have 2 of these submissions one with /genre and the other with /limit, when they are alone in the code they work but when I have both of them in there one of them gives me a URL error. Here is the genre function in python.
"test()">.
#app.route("/recommend/genre/<seed_genres>")
def recommend_two(seed_genres):
endpoint_url = "https://api.spotify.com/v1/recommendations?"
limit=2
market="US"
#seed_genres="indie"
target_danceability=0.9
combo = ""
q=drake&type=artist&limit=5'
query = f'{endpoint_url}limit={limit}&market={market}&seed_genres=.
{seed_genres}&target_danceability={target_danceability}'
token = getAccessToken(clientID, clientSecret)
response =requests.get(query,
headers={"Content-Type":"application/json",
"Authorization":"Bearer " + token})
json_response = response.json()
head_one = "<h1/>"
head_two = "</h2"
for i in json_response['tracks']:
combo += (f"\"{i['name']}\" by {i['artists'][0]['name']}")
return (head_one+combo+head_two)

Related

I am trying to intergrate mpesa payment api to dynamically pass the store price and the correct response

I have been trying to intergrate mpesa API and make my payment dynamically I manage to see the correct value in my cart on my phone stk push but on the web browser I get an error local variable 'order' referenced before assignment and the console gives me a success message without me incorrectly putting in my pin, thank you.
Please please help me solve this I am still a newbie in PYTHON.
def mpesaToken(request):
ckey = 'hOdosm1nU1tXMsT0yPTGjnHDgIUSxx8z'
csecret = 'mrgGSIdbDOZaVrZl'
apiurl = 'https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials'
r = requests.get(apiurl, auth=HTTPBasicAuth(ckey, csecret))
mptoken = json.loads(r.json)
valida = mptoken['access_token']
return HttpResponse(valida)
def lipaOnline(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.orderitem_set.all()
cartItems = order.get_cart_items
else:
items = []
accesstoken = MpesaToken.valida
apiurl = "https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest"
headers = {"Authorization":"Bearer %s" % accesstoken}
request = {
"BusinessShortCode": Lipa.bscode,
"Password": Lipa.decode_pass,
"Timestamp": Lipa.lipatime,
"TransactionType": "CustomerPayBillOnline",
"Amount": order.get_cart_total,
"PartyA": 25471234567,
"PartyB": Lipa.bscode,
"PhoneNumber": 25471234567,
"CallBackURL": "https://sandbox.safaricom.co.ke/mpesa/",
"AccountReference": "HAC",
"TransactionDesc": "testeltd"}
response = requests.post(apiurl, json=request, headers=headers)
return HttpResponse('Success')
print(request)
The problem is you are trying to pick a value from a computed value, it doesn't understand that it's supposed to retrieve that query(order.get_cart_total) before it assigns that value into your other variable Amount so what works for me is that I set the variable first before invoking it and to be sure you can also put it as a global variable.
so simply do
global totalcart = order.get_cart_total
first then
"Amount" : totalcart'
...

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

Uncaught syntax error: unexpected string with json response

I'm getting an uncaught syntax error: unexpected string the chrome console when running ajax where I am trying to add a row to the bottom of a html table with the saved data returned with json. I really can't spot it....
function create_person() {
console.log("create person is working!")
$.ajax({
url : "{% url 'tande:create_person' %}",
type: "POST",
data: { first_name : $('#person-first-name').val(), surname : $('#person-surname').val(), email : $('#person-email').val(), coach_id : $('#person-coach-id').val(), is_coach : $('#person-is-coach').val(), position : $('#person-position').val(), contract_type : $('#person-contract').val()},
success : function(json) {
$('#person-first-name').val('');
$('#person-surname').val('');
$('#person-email').val('');
$('#person-coach-id').val('');
$('#person-is-coach').val('');
$('#person-position').val('');
$('#person-contract').val('');
console.log(json);
// ERROR OCCURS ON FOLLOWING LINE
var html = '<tr><td>'+json.personid+'</td><td>'+json.personfirstname+' '+json.personsurname'</td><td>'+json.personposition+'</td><td>'+json.personcontract+'</td><td>'+json.personemail+'</td><td>'+json.personcoachid+'</td></tr>';
console.log("success");
$('div#talk').html(html);
console.log(html)
},
error : function(xhr,errmsg,err) {
// $('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
// " <a href='#' class='close'>×</a></div>"); // add the error to the dom
console.log("uh oh");
}
});
};
The data is saved successfully and the json object is returned to the console, I just can't display it.
def create_person(request):
if request.method == "POST":
print "request post data in view"
firstname = request.POST.get('first_name')
print firstname
lastname = request.POST.get('surname')
emailadd = request.POST.get('email')
coachid = request.POST.get('coach_id')
isacoach = request.POST.get('is_coach')
positionheld = request.POST.get('position')
contracttype = request.POST.get('contract_type')
response_data = {}
starfruit = Person(first_name=firstname, surname=lastname, email=emailadd, coach_id=coachid, assign_as_coach=isacoach, position=positionheld, contract_type=contracttype)
starfruit.save()
response_data['personfirstname'] = starfruit.first_name
response_data['personsurname'] = starfruit.surname
response_data['personemail'] = starfruit.email
response_data['personcoachid'] = starfruit.coach_id
response_data['personiscoach'] = starfruit.assign_as_coach
response_data['personposition'] = starfruit.position
response_data['personcontract'] = starfruit.contract_type
response_data['personid'] = starfruit.id
# response_data = {
# ''
# }
print response_data
return JsonResponse(response_data)
else:
print "no post request in view"
return JsonResponse(response_data)
The error I'm getting in the console is just as follows:
(index):845 Uncaught SyntaxError: Unexpected string
and it refers to the line I've highlighted above
var html = '<tr><td>'+json.personid+'</td><td>'+json.personfirstname+' '+json.personsurname'</td><td>'+json.personposition+'</td><td>'+json.personcontract+'</td><td>'+json.personemail+'</td><td>'+json.personcoachid+'</td></tr>';
I'm unsure how else to approach this...
You're missing a + between json.personsurname and the following '</td><td>'.
Generally it's a really bad idea to build up HTML like that; this sort of thing is easy to miss.

JSON data not reaching view pyramid

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
});

Categories