Running python script using html in Flask

Question:

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><a href="{{ url_for('generate') }}">click me</a></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.

Asked By: Ann

||

Answers:

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><a href="{{ url_for('generate') }}">click me</a></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 🙂

Answered By: Taehan Stott
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.