flask python,javascript variable issue? - javascript

my flask code section that have issue
main.py
from flask import Flask, render_template, url_for
import pandas as pd
import json
app = Flask(__name__)
#app.route('/')
def home():
df = pd.read_csv('test.csv')
df = df.groupby('name')['marks'].sum()
j = df.to_json(orient='index')
return render_template("work.html",s=j)
if __name__ == "__main__":
app.run(debug=True)
and i want to pass j into my javascript file that is look like that
work.js
//pie chart
var s = {{ j|safe }};
var keys = [];
for(var k in s) keys.push(k);
var value = [];
for (var k in s) value.push(s[k]);
var data = [{
values: value,
labels: keys,
type: 'pie'
}];
var layout = {
height: 400,
width: 500
};
Plotly.newPlot('myDiv1', data);
work.html
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="navbar"><span>data representation with Plotly.js</span></div>
<div class="wrapper">
<div id="myDiv1"></div>
<script type="text/javascript" src={{ url_for('static', filename='work.js')}}>
</script>
</div>
</body>
</html>
how to pass j variable in flask to s variable in javascript file that render with html page and show right content or say that no graph shown
Thank you

You can't do that. You have to return that json in your flask method and make an ajax request from javascript.
from flask import jsonify
#app.route('/')
def home():
j = df.to_json(orient='index')
return jsonify(j)
I don't know if flask has something like JsonResponse as django has. If yes you should use that like: return JsonResponse(j)
$.ajax({url: "your_url", success: function(result){
//result is what you returned from flask
}});

Related

get parameter input from website, run python script and get output to server

I'd like to preface this by saying that I have ZERO javascript or flask knowledge.
Basically, I have made an html interface from which I am retrieving some user input. I would like to use this input as a parameter in a python function, run this function and then somehow retrieve the output of this function (which is a string btw) to display it on the website.
Here is my code (which obviously doesn't work):
python:
import get_response
app= Flask(__name__)
#app.route('/rep_bot',methods=['GET','POST'])
def bot_rep_py():
outputpy=get_response(request.data)
return render_template("output.html",output=outputpy)
the javascript function that I want to perform the sending and retrieving of information:
function bot_rep_js(input) {
$.post("http://127.0.0.1:5000/rep_bot", {
js_input:input
});
return console.log(data)
}
I have tried a few other things that didn't work anyway so I'm not gonna write them here so as not to hurt your eyes anymore.
If anyone would be so kind as to show and explain to me what I have to change in order for my code to behave the way I want it to I'd be very grateful.
$.post has option to assign function which will be executed when it get response. And inside this function you should get data and use it to (re)place it in HTML.
$.post("http://127.0.0.1:5000/rep_bot",
{js_input: input},
function(data){console.log(data);}
)
Minimal working example
$.post sends POST data with "Hi" to flask and flask sends back JSON data with answer "Hello World!" which $.post gets in assigned function and it puts this answer in <div>
I used render_template_string instead of render_template so all data are in one file and everyone can simply copy and run it.
from flask import Flask, request, render_template_string, jsonify
app= Flask(__name__)
def get_response(data):
print('data:', data) # "Hi"
return "Hello World!"
#app.route('/rep_bot', methods=['GET','POST'])
def bot_rep_py():
if request.method == 'POST':
input_text = request.form["js_input"]
print('input_text :', input_text)
output_text = get_response(input_text)
print('output_text:', output_text)
return jsonify({'answer': output_text})
else:
return "???"
#app.route('/')
def index():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<button>Send "Hi"</button>
<div id="answer"></div>
<script>
$(function(){
console.log("ready 1");
function bot_rep_js(input) {
console.log(input)
$.post("http://127.0.0.1:5000/rep_bot",
{js_input: "Hi"},
function(data){
console.log(data);
$("#answer").text(data.answer);
},
);
}
$("button").click(bot_rep_js);
console.log("ready 2");
});
</script>
</body>
</html>
''')
if __name__ == '__main__':
app.run(debug=True)#, use_reloader=False)
EDIT:
The same without jQuery using standard fetch() and .then() to execute function when it gets response from server.
from flask import Flask, request, render_template_string, jsonify
app= Flask(__name__)
def get_response(data):
print('data:', data) # "Hi"
return "Hello World!"
#app.route('/rep_bot', methods=['GET','POST'])
def bot_rep_py():
if request.method == 'POST':
input_text = request.form["js_input"]
print('input_text :', input_text)
output_text = get_response(input_text)
print('output_text:', output_text)
return jsonify({'answer': output_text})
else:
return "???"
#app.route('/')
def index():
return render_template_string('''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
// function `bot_rep_js` has to be before `onclick="bot_rep_js()"`
console.log("ready 1");
function bot_rep_js(input) {
console.log("input: " + input)
// create form and add file
var formdata = new FormData();
formdata.append("js_input", "Hi");
// create AJAX connection
fetch("http://127.0.0.1:5000/rep_bot", {
method: 'POST',
body: formdata,
//headers: {"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"} // makes only problem
}).then(function(response) {
return response.json(); // get JSON from response
}).then(function(data) {
console.log(data);
document.querySelector("#answer").innerText = data.answer;
}).catch(function(err) {
console.log("Fetch problem: " + err.message);
});
}
console.log("ready 2");
</script>
<button onclick="bot_rep_js()">Send "Hi"</button>
<div id="answer"></div>
</body>
</html>
''')
if __name__ == '__main__':
app.run(debug=True)#, use_reloader=False)
fetch() could send data as JSON but I send as FORM to make it similar to previous code.

GET and POST methods and how they should be used

I am building a locally hosted website via flask that I will use to scrape sites like craigslist. I have run into some problems getting the main index page to update correctly. I am a novice when it comes to this sort of fullstack level development.
Why is the front page of my website not updating when I change the variable being passed into the javascript? Whenever I POST(i.e. make a submission via a search box, the Entries variable doesn't appear to update. I am very new to javascript so please be gentle. ;)
below is the code:
<head>
<title>Flask app</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div class="topnav">
<a class="active" href="#home">Home</a>
About
Contact
<form class = "form" action="/index" method="POST">
<input id ="textbox" name="textbox" type="text" placeholder="Search..">
<button type="submit">submit</button>
</form>
</div>
<p id="search-query"> you searched: </p>
<div id="div1">
<p id="p1"></p>
<p id="p2"></p>
</div>
<script>
var value = $('.textbox').val();
//alert(value);
$("button").click(function (e) {
e.preventDefault();
var value = $("#textbox").val();
//alert(value);
$.ajax({
type: 'POST',
url: "index",
data: JSON.stringify({"text" : value}),
contentType: 'application/json; charset=utf-8',
success: function(data){
$("#search-query").text("you search: " + data["text"]);
//alert(JSON.stringify(data));
}
});
});
var jsonz = {{ entries|tojson }};
var s = JSON.parse(jsonz);
var i;
for (i = 0; i < s.length; i++) {
var para = document.createElement("p");
var node = document.createTextNode(s[i].product_name + "\n" + s[i].product_link);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
}
</script>
</body>
</html>
and here is app.py
from scraper import scrape
from flask import Flask, render_template, jsonify, make_response, request
import json
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
search = request.get_json()
search = json.dumps(search)
search = json.loads(search)
search = search['text']
print search
#search = json.loads(search)
entries = json.dumps(scrape(search))
return render_template('index.html', entries = entries)
elif request.method == "GET":
entries = json.dumps(scrape("cars"))
return render_template('index.html', entries= entries)
else:
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
you can make a check below these steps
1、check your ajax url is define in your flask app, your flask app do not define '/index', so please check your api is work correctly, like this
#app.route("/index", methods=['GET', 'POST'])
2、ajax receive data but not html page, so your flask should return data(i.e,{text:"xxxx"}),then you can use $("#search-query").text("you search: " + data["text"]); to update, like this
#app.route("/index", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
search = request.get_json()
search = json.dumps(search)
search = json.loads(search)
search = search['text']
print search
#search = json.loads(search)
entries = json.dumps(scrape(search))
return entries
hope it can help you!

How do I update the javascript in my index.html file?

I am currently making a flask app. I cant get the javascript to update whenever I do a post request. It just stays the same. Here is the code I am focused on that is supposed to update whenever I do a post request:
var jsonz = {{ entries|tojson }};
var s = JSON.parse(jsonz);
var i;
for (i = 0; i < s.length; i++) {
var para = document.createElement("p");
var node = document.createTextNode(s[i].product_name + "\n" + s[i].product_link);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
I am very new to javascript. I want to pass in "entries" from the back end and then have that json be displayed in the index.html.
Someone please help.
Here is the full code for index.html
<!DOCTYPE html>
<html>
<head>
<title>Flask app</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div class="topnav">
<a class="active" href="#home">Home</a>
About
Contact
<form class = "form" action="/index" method="POST">
<input id ="textbox" name="textbox" type="text" placeholder="Search..">
<button type="submit">submit</button>
</form>
</div>
<p id="search-query"> you searched: </p>
<div id="div1">
<p id="p1"></p>
<p id="p2"></p>
</div>
<script>
var value = $('.textbox').val();
//alert(value);
$("button").click(function (e) {
e.preventDefault();
var value = $("#textbox").val();
//alert(value);
$.ajax({
type: 'POST',
url: "index",
data: JSON.stringify({"text" : value}),
contentType: 'application/json; charset=utf-8',
success: function(data){
$("#search-query").text("you search: " + data["text"]);
//alert(JSON.stringify(data));
}
});
});
var jsonz = {{ entries|tojson }};
var s = JSON.parse(jsonz);
var i;
for (i = 0; i < s.length; i++) {
var para = document.createElement("p");
var node = document.createTextNode(s[i].product_name + "\n" + s[i].product_link);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
}
</script>
</body>
</html>
and here is app.py
from scraper import scrape
from flask import Flask, render_template, jsonify, make_response, request
import json
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
#app.route("/index", methods=['GET', 'POST'])
def index():
if request.method == 'POST':
search = request.get_json()
search = json.dumps(search)
search = json.loads(search)
search = search['text']
print search
#search = json.loads(search)
entries = json.dumps(scrape(search))
return entries
elif request.method == "GET":
entries = json.dumps(scrape("cars"))
return render_template('index.html', entries= entries)
else:
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
Again, I want the scraped data in the form of "entries" to be passed to the front end and displayed in the html.
Thanks for any help!
HERES WHAT I DID TO FINALLY GET IT WORKING
<!DOCTYPE html>
<html>
<head>
<title>Flask app</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div class="topnav">
<a class="active" href="#home">Home</a>
About
Contact
<form class = "form" action="/index" method="POST">
<input id ="textbox" name="textbox" type="text" placeholder="Search..">
<button type="submit">submit</button>
</form>
</div>
<p id="search-query"> search results: </p>
<div id="div1">
<p id="p1"></p>
<p id="p2"></p>
</div>
<script>
var value = $('.textbox').val();
//alert(value);
$("button").click(function (e) {
e.preventDefault();
var value = $("#textbox").val();
alert(value);
$.ajax({
type: 'POST',
url: "parse_data",
data: JSON.stringify({"text" : value}),
contentType: 'application/json; charset=utf-8',
success: function(data){
$("p#search-query").append(data.data);
alert(JSON.parse(data));
}
});
});
</script>
</body>
</html>
and app.py
from scraper import scrape
from flask import Flask, render_template, jsonify, make_response, request
import json
app = Flask(__name__)
#app.route("/")
def index():
return render_template('index.html')
#app.route("/parse_data", methods=['POST'])
def parse_data():
search = request.get_json()
search = json.dumps(search)
search = json.loads(search)
search = search['text']
print search
#search = json.loads(search)
entries = json.dumps(scrape(search))
#entries = jsonify({'name' : entries})
return jsonify({'data' : render_template('response.html', entries= entries)})
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)

Getting chart.js to work with Django and Apache

I have the following setup. I've a simple index.html being served through apache. It looks like the following.
<!DOCTYPE html>
<html lang='en'> <meta http-equiv="content-type" content="text/html; charset=UTF8"> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <canvas id="myChart"></canvas> <script language="JavaScript" src="/customcharts.js"> </script> </body> </html>
All the above does is to try and place a line chart on the browser. It uses chart.js. To accomplish this the customcharts.js tries to connect to a locally running django server. The above html is being served through apache running on port 8080 while django runs on port 8090.
the customcharts.js looks as follows
function renderChart(data){
console.log(data)
console.log(data.labels)
defaultLabels = data.labels
defaultData = data.defaultData
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: defaultLabels,
datasets: [{
lineTension: 0,
label: 'Activity Profile',
data: defaultData,
}]
}
})
}
var endpoint = 'http://localhost:8090/polls/alice/'
var defaultData = []
var defaultLabels = []
$.ajax({
url: endpoint,
dataType: "JSONP",
success: renderChart,
method: 'GET'
}
);
Further, my django view is
def json_response(func):
"""
A decorator thats takes a view response and turns it
into json. If a callback is added through GET or POST
the response is JSONP.
"""
def decorator(request, *args, **kwargs):
objects = func(request, *args, **kwargs)
if isinstance(objects, HttpResponse):
return objects
try:
data = simplejson.dumps(objects)
if 'callback' in request.REQUEST:
# a jsonp response!
data = '%s(%s);' % (request.REQUEST['callback'], data)
return HttpResponse(data, "text/javascript")
except:
data = simplejson.dumps(str(objects))
return HttpResponse(data, "application/json")
return decorator
epoch = datetime.datetime.utcfromtimestamp(0)
r = redis.StrictRedis(host='localhost', port=6379, db=0)
threat_list = ['date', 'categories', 'mix']
#json_response
def index(request, uid):
print uid
uid = uid.rstrip('/')
_key = uid
retjsondict = {}
input_keys = [_key + ':' + x for x in threat_list]
k = input_keys[0]
retdict = {}
if r.exists(k):
retvalue = r.get(k).strip('"')
xdata_dt = [x.split(':')[0] for x in retvalue.split(' ')]
ydata_dt = [x.split(':')[1].rstrip(',') for x in retvalue.split(' ')]
retdict['defaultLabels'] = xdata_dt
retdict['defaultData'] = ydata_dt
print retdict
return JsonResponse(retdict)
the index is the real view and the json_response is a decorator.
However, when I try and view it on a browser using http://localhost I get the following error
XMLHttpRequest cannot load http://localhost:8090/polls/alice/. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
Could someone point to me what I'm doing off?
Any help/pointers appreciated.
If customcharts.js is within the static/yourapp you need to load your script as follows:
<script src="{% static 'yourapp/customcharts.js' %}"></script>
Don't forget to call {% load staticfiles %}
Then, a static resource can't call a view, you need to get the json data in the view and then pass it to the javascript function.
Your template should look as follows:
{% load staticfiles %}
<!DOCTYPE html>
<html lang='en'>
<meta http-equiv="content-type" content="text/html; charset=UTF8">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script language="JavaScript" src="{% static 'yourapp/customcharts.js' %}"> </script>
<script language="JavaScript">
$.getJSON("{% url 'index' %}", function(data) { // 'index' is the name of the view in your urls.py
renderChart(data);
});
</script>
</head>
<body>
<canvas id="myChart"></canvas>
</body>
</html>
Hope this helps.
Use 'polls' instead of 'index'

How can i send slider value from jQuery or javascript to python Flask?

I have a round slider with the slider value on client side or web page. when the user changes the slider position, the client has to send the value to the server. Here i use python flask as a server side. So the value has to be sent from j Query or java script to flask. I tried with the following code. But when i use Ajax, the web page becomes blank. It doesn't show the slider. If i remove the Ajax way of sending, the slider appears but value is not sent to server.
CLIENT SIDE:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery roundSlider - JS Bin</title>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.css">
<script src="//cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.js"></script>
</head>
<body>
<div id="slider"></div>
<div id="slide"></div>
<script>
$(document.ready(function(){
var value;
$("#slider").roundSlider({
sliderType: "min-range",
change: function(){
var obj1 = $("#slider").data("roundSlider");
value = obj1.getValue();
$("#slide").html(value);
});
$.ajax({
type: 'POST',
url: "{{url_for('test')}}",
contentType: 'application/json;charset=UTF-8',
data: {'data':value}
});
});
</script>
</body>
</html>
SERVER SIDE:
def flask():
connection()
app = Flask(__name__, template_folder='Templates')
#app.route('/test/', methods=['GET', 'POST'])
def test():
if request.method == "POST":
value=request.json['data']
print(value)
return render_template('roundslider1.html')
if __name__ == "__main__":
app.run(host='192.168.42.1',port=2030, debug=True)
After reading some more documentations, i used the below code to send the variable from j Query to flask server.
CLIENT SIDE:
var value;
$("#slider").roundSlider({
sliderType: "min-range",
change: function(){
var obj1 = $("#slider").data("roundSlider");
value = obj1.getValue();
$.getJSON('/valueofslider', {
a:value
});
SERVER SIDE:
#app.route('/valueofslider')
def slide():
a = request.args.get('a')
print (a)

Categories