I'm at a beginner at coding and i'm stuck at the final closing :|
i'm using python 2.7
this is my serever.py
from flask import Flask, render_template,request,jsonify
import requests
import json
import new
app = Flask(__name__)
#serve homepage
#app.route('/', methods=["GET","POST"])
def homepage():
return render_template('page2.html')
#app.route('/page3.html', methods=["POST"])
def result_matchup():
h= request.form['h']
a= request.form['a']
l= request.form['l']
p= request.form['p']
result = json.dumps(new.calc(h,a,l,p))
return render_template('page3.html',result=result)
if __name__ == "__main__":
app.run(debug=True)
when i ask for return result for checking myself, this is the output:
{"f": 197.1, "k": 196}
this is my page3.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<center><h1>Final = {{f}}</h1></center>
</body>
</html>
the output for all this is
"Final = "
,while I expect for Final = 197.1.
what am I doing wrong? any help?
thanks!
I assume new.calc returns a dictionary. No need to use json.dumps to stringify that before passing to your template. So instead try:
result = new.calc(h,a,l,p)
result should now be a dictionary, with the keys 'f' and 'k'
Therefor in the template you should access this dictionary, as you would in python:
<center><h1>Final = {{result['f']}}</h1></center>
I would also advise using a later version of python since 2.7 is unsupported now, and making this change early will prevent you having to make already written code, 3.x compatible later.
Two suggestions:
You serialize your result as JSON writing result = json.dumps(new.calc(h,a,l,p)). However, you should directly pass a Python object to render_template. In fact, that's one of the strengths of Jinja templating: You do not need to pass JSON, but you can handle Python objects directly. So just write result = new.calc(h,a,l,p).
Second, within the Jinja template, you have to access the objects as you passed them through your render_template function. In your case, <center><h1>Final = {{result['f]}}</h1></center> should do the job.
Related
I want to make a variable with Python, and then console.log() the variable in JavaScript. I know how to access the variable in JavaScript, but I don't know how to make the Python script run when the page is loaded. How can I do this?
Unlike Javascript, you can't run Python directly in the browser. You would need Python to run server-side. A possible alternative may be to use transcrypt to generate javascript equivalents of Python for a frontend-only solution.
For instance, transcrypt allows you to "import" python modules into JavaScript. Here, a python script called hello.py is "imported" into the context and can be called form javascript like hello.solarSystem.greet()
<script type="module">import * as hello from './__target__/hello.js'; window.hello = hello;</script>
<h2>Hello demo</h2>
<p>
<div id = "greet">...</div>
<button onclick="hello.solarSystem.greet ()">Click me repeatedly!</button>
<p>
<div id = "explain">...</div>
<button onclick="hello.solarSystem.explain ()">And click me repeatedly too!</button>
See the transcrypt docs for more info.
Otherwise, you'd probably be running a Python webserver on the backend for this use-case. Something like flask.
from flask import Flask, render_template_string
app = Flask(__name__)
def do_something():
"""Returns an interesting value"""
return "foo"
template = """
<html>
<script>
console.log('{{ value }}')
</script>
"""
#app.route('/')
def home():
my_value = do_something()
return render_template_string(template, value=my_value)
app.run(debug=True)
I am doing a CTF challenge, but my question is not about how to solve it, rather the syntax. The challenge is to read the secret key in Flask server's configuration. It is stored in the app.secret_key variable and I want to alert it on the screen by XSS.
Question: how can I access that variable in Flask code from javascript and put it in <script>alert(variable)</script> snippet?
I tried <script type="text/javascript">let v="{{=app.secret_key}}"; alert(v); </script> but it gave Internal Server Error.
First, it must be said, in general you should should absolutely not do this. app.secret_key should never, ever be exposed publicly and should be regarded as a closely guarded secret. Hence the name. But since you're doing this for presumably good reasons involving your game, let's continue.
Probably the simplest way to expose Python variables to JavaScript is directly in the template by dumping JSON. Consider this code:
import json
from flask import Flask, render_template
app = Flask(__name__)
app.secret_key = 'THIS IS SECRET'
#app.route('/')
def hello_world():
server_vars = {
'secretKey': app.secret_key,
'favoriteFoods': ['Eggs', 'Spam']
}
return render_template(
'hello.html',
server_vars=json.dumps(server_vars)
)
if __name__ == '__main__':
app.run()
We're rendering the template hello.html and sending it a template variable, server_vars, which is a rendered JSON string of the same server-side variable, which is a dictionary. This enables us to send any number arbitrary JSON-compatible variables to JavaScript. See hello.html:
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
window.serverVars = {{ server_vars | safe }};
alert(window.serverVars.secretKey)
console.log('btw, my favorite foods are', window.serverVars.favoriteFoods)
</script>
</body>
</html>
Notice that in addition to sending secretKey, we actually sent a Python list, which was converted into an array in JavaScript.
I created a website with HTML/CSS. I also used Javascript for events (click on button, ...).
Now I want to connect a Python script with it and more importantly, return the results from my Python functions to my website and display (use) them there.
Consider something like this: I have a website with an input field and a button. If you click on the button, a Python script should run which returns if the input is an odd or even number (of course you don't need Python for this specific case, but that's what I want to do).
From my research I believe Flask is the library to be used for this, but I really don't know how to do it. I found very few examples. I would really appreciate if someone could implement the above example or tell me how to do it exactly.
I know there are already some questions about that concept here online, but as I said, with very few examples.
You're right about Flask being a good solution for this and there are examples and tutorials everywhere. If what you want is just to run a specific function on a button press and get something back in javascript, I've put a quick example is below.
# app.py
from flask import Flask, render_template
from flask import jsonify
app = Flask(__name__)
# Display your index page
#app.route("/")
def index():
return render_template('index.html')
# A function to add two numbers
#app.route("/add")
def add():
a = request.args.get('a')
b = request.args.get('b')
return jsonify({"result": a+b})
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
This can then be run with python app.py and make sure your index.html is in the same directory. Then you should be able to go to http://127.0.0.1/ and see your page load.
This implements a function which adds two numbers, this can be called in your javascript by calling http://127.0.0.1/add?a=10&b=20. This should then return {"result": 30}.
You can grab this in your javascript using the code below and place this code in your buttons on click callback.
let first = 10;
let second = 20;
fetch('http://127.0.0.1/add?a='+first+'&b='+second)
.then((response) => {
return response.json();
})
.then((myJson) => {
console.log("When I add "+first+" and "+second+" I get: " + myJson.result);
});
This should be the barebone basics, but once you can submit data to Flask and get data back, you now have an interface to run things in Python.
Edit: Full Front-end example
https://jsfiddle.net/4bv805L6/
I really appreciate time spent on this answer. But the answer did not help me in the way I needed it. At that point I had no clue what to do, but since thenbI figured it out some time ago and I thought I should share my solution here:
That's app.py:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/stick', methods=['GET', 'POST'])
def stick():
if request.method == 'POST':
result = request.form['string1'] + request.form['string2']
return render_template('index.html', result=result)
else:
return render_template('index.html')
if __name__ == "__main__":
app.run()
And that's index.html (put in the folder templates):
<!DOCTYPE html>
<html>
<body>
<h3> Stick two strings </h3>
<form action="{{ url_for('stick') }}" method="post">
<input type="text" name="string1">
<input type="text" name="string2">
<input type="submit" value="Go!">
<p id="result"></p>
</form>
<script>
document.getElementById("result").innerHTML = "{{result}}"
</script>
</body>
</html>
In the terminal, type in python app.py and it should work.
So I'm creating a python app that counts detected objects using OpenCV then passing the counter variable to Flask server using the following HTTP post request:
requests.post('http://127.0.0.1:5000', json = {'count': count})
, the flask sever receives the variable then pass it to a JavaScript within the html template, here is the code of flask server:
app = Flask(__name__)
#app.route("/",methods=['GET', 'POST'])
def index():
content = request.get_json(silent=True)
if content :
cnt = content.get('count') #get JSON from OpenCV every time the count is updated
print cnt # here it prints the variable to the cmd and show me the count update
return render_template("test.html", cnt = cnt); #here the value is passed as zero ?!
if __name__ == "__main__":
app.run(debug=True)
and when I run the 'test.html' template it only show me the 'cnt' variable = 0, although I'm getting the updated value constantly from my OpenCV code to my flask server.
here is the script part of my 'test.html'
<p>People count: <span id="counti"></span></p>
<script>
var countn = '{{cnt}}';
document.getElementById('counti').innerHTML = countn
</script>
I want my 'count' variable to pass smoothly from OpenCV and receive into my Javascript to be able to make my web-app able to make decisions based on the count of objects observed by OpenCV.
What is the optimal way to do this ?
I really appreciate your help!
This is my first dive into Flask + Jinja, but I've used HandlebarsJS a lot in the past, so I know this is possible but I'm not sure how to pull this off with Flask:
I'm building an app: a user enters a string, which is processed via python script, and the result is ajax'd back to the client/Jinja template.
I can output the result using $("body").append(response) but this would mean I need to write some nasty html within the append.
Instead, I'd like to render another template once the result is processed, and append that new template in the original template.
Is this possible?
My python:
from flask import Flask, render_template, request, jsonify
from script import *
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/getColors')
def add_colors():
user = request.args.get("handle", 0, type = str)
return jsonify(
avatar_url = process_data(data)
)
if __name__ == '__main__':
app.run()
There is no rule about your ajax routes having to return JSON, you can return HTML exactly like you do for your regular routes.
#app.route('/getColors')
def add_colors():
user = request.args.get("handle", 0, type = str)
return render_template('colors.html',
avatar_url=process_data(data))
Your colors.html file does not need to be a complete HTML page, it can be the snippet of HTML that you want the client to append. So then all the client needs to do is append the body of the ajax response to the appropriate element in the DOM.