Running python script using html in Flask - python

I'm new to Flask and I'm trying to run a python script from background upon click on a button in a html page. Here is my code:
from flask import *
from functools import wraps
import sqlite3
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
#app.route('/generate')
def generate():
return render_template('process.html')
and my process.html is as follows:
<html>
<head>
<body>
Processing...
<script>
exec('python /pth to my python file/myfile.py')
</script>
</body>
</head>
</html>
and home.html is as follows:
{% extends "template.html" %}
{% block content %}
<div class = "jumbo">
<h2> Home</h2>
<br/>
<p>click me</p>
<p> lorem epsum </p>
<div>
{% endblock %}
I'm working on linux and I do not know whether it is possible to use exec in html as shown above. However exec command inside .html file is not executing. I'm still new to flask and I would appreaciate any suggestion on how to make it work.

The <script> tag in HTML is specifically for running client-side JavaScript code. Back-end logic should be done in the views. If you're just looking to execute a line of code that is present in myfile.py, you should put it in a function in that file and import it using from myfile import functionname or simply have that code present in the views (the latter being the proper way to do it in most cases). For example, if myfile.py contained print 'Hello World!' then your views should look like this:
from flask import *
from functools import wraps
import sqlite3
app = Flask(__name__)
#app.route('/')
def home():
return render_template('home.html')
#app.route('/generate')
def generate():
print 'Hello World!'
return render_template('process.html')
If you did it this way, you wouldn't have to split all of your code up into separate files. Unfortunately though, the template would be rendered after the code is executed, so 'Processing...' as shown in your process.html template would display after it has already been processed. As far as Flask goes, the best way that I'm aware of to show the user that the process took place would be to redirect back to the page and flash a message, like this:
#app.route('/generate')
def generate():
print 'Hello World!'
flash('Process complete!')
return redirect(url_for(home))
and then in home.html you would have something like this (from Flask 0.11 Documentation):
{% extends "template.html" %}
{% block content %}
<div class = "jumbo">
<h2> Home</h2>
<br/>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<p>click me</p>
<p> lorem epsum </p>
<div>
{% endblock %}
If you wanted something like 'Processing...' to display on the page, that's when you would want to use JavaScript.
Hopefully this helps :)

Related

Having problems with the usage of a block in Flask

so I tried bulding a (small) website (for learning purposes) and had a few problems with the usage of a block.
I have the feeling that the problem is something obvious, but I can't figure it out.
Here is my code:
# main.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def home():
return render_template("main.html")
if __name__ == "__main__":
app.run(debug=True)
# main.html
<!DOCTYPE html>
<head>
<title>
{% block title %}{% endblock %}
</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
# mainexdended.html
{% extends "main.html" %}
{% block title %}Test{% endblock %}
{% block content %}
<h1> Content Test </h1>
{% endblock %}
Now, when I run the code, I just get a blank page. Everything defined in the mainextended.html gets ignored.
How can I change that?
That's because you are rendering main.html, not mainextended.html.
You need to change
#app.route("/")
def home():
return render_template("mainextended.html")
Than you should see the contents of both, main.html and mainextended.html
If you use "extend" you always want to render the "extending" html, there is also a function to include content tho, which would work the other way round.

Flask render loading page until results are generated (then load result page)

I’m very new to Flask (and web development in general) but so far I think I’m sorta getting it?
anyway, I want to make a web app where the user uploads a file, the file will then be analyzed using Flask (mainly python and some shell) and the results then need to be reported back to the user.
I what have until now is a page where the user can upload their file and where a job id is assigned to the file. What I want next is that the users get redirected to a page with the jobid is the URL like
#app.route("/<jobid>", methods=['GET', 'POST’]) and that a loading page is displayed until the results files exist > then another page needs to be displayed.
The problem: I have no clue how to do that. This is what I got so far:
python:
#app.route("/<jobid>", methods=['GET', 'POST'])
def main_process(jobid):
if not jobid in JOBID_DICT:
return render_template("upload_fail.html")
else:
des = JOBID_DICT.get(jobid)
if request.method == "GET":
return render_template("complete.html", jobid=jobid)
if request.method == "POST": ##POST METHOD does not work yet
#this is where I need to run the analysis ig?
return render_template("results.html")
complete html:
{% extends "templates/base.html" %}
{% block title %}
succesfull upload
{% endblock %}
{% block main %}
<h1>file was uploaded</h1>
<p>starting process</p>
<p>once process is completed page will be refreshed.</p>
<p>Job ID: {{ jobid }} </p>
{% endblock %}
results.html:
{% extends "templates/base.html" %}
{% block title %}
{{jobid}}
{% endblock %}
{% block main %}
<h1>this the results page</h1>
<p>which I still need to code</p>
{% endblock %}
base.html (i use bootstrap and other css files but removed it for clarity):
<!doctype html>
<html lang="en">
<head>
<title> {% block title %}{% endblock %}</title>
</head>
<body>
<main>{% block main %}{% endblock %}</main>
</body>
</html>
If someone could help, it would be great. I mainly know python and R, and my HTML + CSS knowledge is from like 5 years ago… but I’m learning. Anyway thanks already.
You can use threading for that.
Put the job on a thread and when it completes update your UI
You can find more here threading

How to run python file within flask?

In my flask application I have a so called 'about' page, from this about page i want to run this python script.
This is the script:
https://github.com/stakeinlinkies/sendwithasmile/blob/master/sendsmile.py and it has 2 dependency xml files.
this is the content of my about page:
{% extends "layout.html"%}
{% block content%}
<h1>about</h1>
<button type="button" class="btn btn-success" >Start A.I.</button>
{% endblock content %}
When I run the program in the command line the prgramm turns on the webcam and a video window pops up and than detects for a smile.
I want to run this on the website so i want the video window to be rendered on my about page.
How can i achieve this.
You'll have to import sendsmile.py file into you main flask app file:
import sendsmile
...
#app.route('/sendsmile', methods=['POST', 'GET'])
def sendsmile():
sendsmile() #run sendsmile
return('', 200)
HTML
{% extends "layout.html"%}
{% block content%}
<h1>about</h1>
<iframe name="iframe1" src="#"></iframe>
Start A.I.
{% endblock content %}

How to pass multiple templates to flask.render_template()

I'm trying to deploy a flask app and I want a flask.render_template() method passed with a list of html files. Here I see it's eligible. http://flask.pocoo.org/docs/0.12/api/#flask.render_template
I'm trying with this code
from flask import Flask, render_template
app = Flask(__name__)
app.debug = True
#app.route('/')
def hello():
templs = ["_header.html", "_footer.html"]
return render_template(templs)
if __name__== '__main__':
app.run()
But actually server returns only the first template from the list.
How to iterate though this list in order to render all templates from the list?
Thanks,
Alex
As far as i see you are trying to render static header and footer. I'd recommend to prepare something like "layout.html" with included header and footer:
//layout.html
<html>
<head>//headhere</head>
<header>//your static header</header>
<main>
{% block body %}
//content will be here
{% endblock %}
</main>
<footer> //your static footer </footer>
</html>
then in "child" templates(ex: index.html)use:
//index.html
{% extends "layout.html" %}
{% block body %}
//your code here
{% endblock %}
It will render header and footer from layout.html and rest from index.html.
You probably don't want to render multiple templates. What you want is to render one template that combines multiple templates. That is the task of templating engine, not Flask. See http://jinja.pocoo.org/docs/dev/templates/ (Flask uses Jinja).
Exactly like #jbasko wrote!
Making use of two {{block}} statements worked for me:
For example, I put in my routes.py
#app.route("/page1")
def page1():
return render_template('page1.html', title='Title')
the page1.html is containing simply two block-specifications
{% extends "page1.html" %}
{% block content %}
<h1> Content </h1>
{% endblock content %}
{% block info %}
<h1> Info </h1>
{% endblock info %}
which gets referenced in layout.html in two separate places:
{% block content %}{% endblock %}
and later
{% block info %}{% endblock %}
Thanks for the help everyone!
you can try this...
from flask import Flask, render_template
app = Flask(__name__)
app.debug = True
#app.route('/')
def hello():
render_header = render_template('_header.html')
render_footer = render_template('_footer.html')
return render_header + render_footer
if __name__ == '__main__':
app.run()

Facebook canvas app in Flask - problems with iFrame and redirect

I am fairly new to python and web development, trying to make a Facebook app with flask.
Used code from this website to get started:
http://ryaneshea.com/facebook-authentication-for-flask-apps
I was able to get the app working when I ran it outside of Facebook (from my webserver), but when I ran it embedded in Facebook (which was the point) new users could not authenticate because of this message (seen in the browser developer console) :
"Refused to display 'https://www.facebook.com/dialog/oauth?scope=email%2C+&redirect_uri=https%3A…F%2Fmywebpage%2Ffacebook_authorized&client_id=1421921424687222' in a frame because it set 'X-Frame-Options' to 'DENY'."
Then I tried to change my template so that website would be open in a Facebook accepted way by adding this code: <script>top.location="/facebook_login";</script>. That kind of worked, but now my application regularly breaks out of Facebook and is shown on the webserver instead.
I guess what should be done is to only show https://www.facebook.com/dialog/oauth?scope=email%2C+&redirect_uri=https%3A…F%2Fmywebpage%2Ffacebook_authorized&client_id=1421921424687222 in top.location=, but am not certain how this can be done without breaking the app.
Do I need to make a new route that refers to this url? Can I make a new if-else statement in the facebook_authorized(resp) method to redirect to the url if some specific condition is true? If so, how can this be done?
I found this older thread which is related to my problem, but there are no python/flask specific solutions in it: Overcoming "Display forbidden by X-Frame-Options".
Any suggestion would be greatly appreciated!
Here is the relevant python code:
oauth = OAuth()
facebook = oauth.remote_app('facebook',
base_url='https://graph.facebook.com/',
request_token_url=None,
# access_token_url='/oauth/access_token',
access_token_url='/oauth/access_token',
authorize_url='https://www.facebook.com/dialog/oauth',
consumer_key=FACEBOOK_APP_ID,
consumer_secret=FACEBOOK_APP_SECRET,
request_token_params={'scope': 'email, '}
)
app = Flask(__name__)
#facebook.tokengetter
def get_facebook_token():
return session.get('facebook_token')
def pop_login_session():
session.pop('logged_in', None)
session.pop('facebook_token', None)
#app.route("/", methods=['GET', 'POST'])
def index():
return render_template('index.html')
#app.route("/facebook_login", methods=['GET', 'POST'])
def facebook_login():
return facebook.authorize(callback=url_for('facebook_authorized',
next=request.args.get('next'), _external=True))
#app.route("/facebook_authorized", methods=['GET', 'POST'])
#facebook.authorized_handler
def facebook_authorized(resp):
next_url = request.args.get('next') or url_for('index')
if resp is None or 'access_token' not in resp:
return redirect(next_url)
session['logged_in'] = True
session['facebook_token'] = (resp['access_token'], '')
return redirect(next_url)
Here are the relevant parts of the template:
<html lang="en">
<head>
{% block head %}
<title>MY_NEW_APP{% block title %}{% endblock %}</title>
<body>
{% block navbar %}
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="#">MY_NEW_APP</a>
<div class="nav-collapse">
{% block navbar_right %}
<ul class="nav pull-right">
{% if not session.logged_in %}
<li>Login or Signup</li>
<!-- <script>top.location="/facebook_login";</script>-->
{% else %}
<li>Logout</li>
{% endif %}
</ul>
{% endblock %}
</div><!--/.nav-collapse -->
</div>
</div>
</div>
{% endblock %}
</head>
</html>

Categories

Resources