[Flask] Flask execute system command / wait / return result ?
David Nieder
davidnieder at gmx.de
Wed Sep 23 01:09:56 CEST 2015
On 22.09.2015 18:38, Piotr Grabowski wrote:
> Hi!
>
> I am in a phase of planning a web application for my group (academic
> research) and would love to get some advice or input from more advanced
> Flask users/devs.
>
> We developed a bioinformatics tool that we run from a command line, it's
> run simply as ./tool_binary <input> <parameters>, so pretty standard stuff.
>
> We also are trying to turn this into an extremely easy-to-use tool for
> biologists and are looking for a proper online framework. We decided that
> Flask could be a great solution to keep the whole framework running.
> (already made it work on Galaxy, but we want to keep it ultra-simple and
> nice-looking)
>
> However, does anyone know if Flask could handle an execution of such
> command line tool, wait for the tool to finish and send back the user the
> generated resulting file ?
>
>
> Best regards,
> Piotr
>
Hi Piotr!
Flask doesn't provide a way to do this kind of stuff innately (afaik).
Basically, you will have to run your program in a second process, take
the results and send them in an http response. However, without knowing
how your program works I can't tell you the best way to go about this.
I think running the program and leaving the request hanging until it has
terminated isn't a good solution. But if you are sure the process will
only take a very short time this is probably fine.
You could start the process, return an id and fetch the results later
with a second request.
A solution I think is very nice, is to stream the results back to the
client. There is a chapter in the docs abouth this:
http://flask.pocoo.org/docs/0.10/patterns/streaming/
Here is a simple but working example that invokes the ping utility and
streams it's output back to the client.
from shelljob import proc
from flask import Flask, Response
app = Flask(__name__)
@app.route('/')
def index():
group = proc.Group()
group.run(['ping', '-c', '10', '8.8.8.8'])
def generator():
while group.is_pending():
data = group.readlines()
for handle, lines in data:
yield lines
return Response(generator(), mimetype='text/plain')
if __name__ == '__main__':
app.run(debug=True)
The shelljob package uses the subprocess module. You could use that
module directly but I think this is more convenient. As you see, it
doesn't require much code to do sth like this.
Also: You probably want to let your users set some arguments to your
program through the web interface. So don't forget to sanitize your
inputs!
I hope this was of any help
David
More information about the Flask
mailing list