Keerthi
Keerthi

Reputation: 21

How to run a python script in the background on click of html button using flask framework

''' upload.html'''

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2 style="color:DodgerBlue;">File Uploader</h2>

<form id = "upload-form" action = "{{ url_for('upload') }}" method="POST" 
 enctype="multipart/form-data">
<input type = "file" name = "file" accept = "files/*" multiple>
<input type = "submit" value = "submit">
</form>
</body>
</html>

''' app.py'''

import os
from flask import Flask, request, render_template, send_from_directory
app = Flask(__name__)

APP_ROOT = os.path.dirname(os.path.abspath(__file__))

@app.route("/")
def index():
    return render_template("upload.html")

@app.route("/upload", methods=["POST"])
def upload():

    target = os.path.join(APP_ROOT, 'Athena_XML_files/')
    print(target)
    if not os.path.isdir(target):
        os.mkdir(target)

    for file in request.files.getlist("file"):
        print(file)
        filename = file.filename
        destination = "/".join([target, filename])
        print(destination)
        file.save(destination)

    return render_template("complete.html")

@app.route('/run_script')
def run_script():
    app.config.from_pyfile("main.py")
    return render_template('result.html')

if __name__ == "__main__":
    app.run(port=4555, debug=True)

'''complete.html'''

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>XML files Uploaded</h1>
<ul><br><br>
<h2><strong>Please click to obtain the result</strong></h2><br><br>
<ul class="nav nav-stacked">
    <li role="presentation"><a href="{{ url_for('run_script') }}">CLICK  
HERE</a></li>
</ul>
</ul>
</body>
</html>

As the XML files are uploaded and the CLICK HERE button is clicked, main.py file should run in the background for which i have made a function in app.py file to run the main.py file.

Uploading works well, but on click of button the main.py file is not running in the background.

Upvotes: 2

Views: 6401

Answers (1)

Artist Unknown
Artist Unknown

Reputation: 21

I'm not sure if your idea is a good one. I posted some small solutions, but you should read this article for a better practice.

1) If you want to run an external script from inside flask, you could use subprocess to run a script from the command line.

@app.route('/run-script')
def run_script():
   result = subprocess.check_output("python main.py", shell=True)
   return render_template('results.html', **locals())

2) If you want to run Python code in background without any return, you could create a thread.

from threading import Thread

@app.route('/run-in-background')
def run_in_background():
    run_func()
    return redirect(url_for('.index'))

def run_func():
    data = { 'some': 'data', 'any': 'data' }
    thr = Thread(target=run_async_func, args=[app, data])
    thr.start()
    return thr

def run_async_func(app, data):
    with app.app_context():
    # Your working code here!
    example_module.do_somthing_with(data)

Not sure if it helps. Both solutions could make a lot mess.

You should read the flask docs. The app.config.from_pyfile function evaluates configuration data from Python code. This is very different than your question.

Upvotes: 2

Related Questions