Running a shell script on a flask

My application was configured with the following app.py file and two .html files: index.html (base template) and upload.html, where the client can see the newly uploaded images. The problem is, I want my program (presumably app.py) to execute the matlab function before the user is redirected to the upload.html template. I found Q&A on how to run bash shell commands on a flask (but it is not a command), but I did not find one for scripts.

The workaround I got was to create a wrapper script: hack.sh that will run the matlab code. In my terminal, this is straight forward:

$bash hack.sh

      

hack.sh:

nohup matlab -nodisplay -nosplash -r run_image_alg > text_output.txt &

      

run_image_alg is my matlab file (run_image_alg.m)

Here is my code for app.py:

import os

from flask import Flask, render_template, request, redirect, url_for, send_from_directory
from werkzeug import secure_filename

# Initialize the Flask application

app = Flask(__name__)

# This will be th path to the upload directory
app.config['UPLOAD_FOLDER'] = 'uploads/'

# These are the extension that we are accepting to be uploaded
app.config['ALLOWED_EXTENSIONS'] = set(['png','jpg','jpeg'])

# For a given file, return whether it an allowed type or not
def allowed_file(filename):
  return '.' in filename and \
    filename.rsplit('.',1)[1] in app.config['ALLOWED_EXTENSIONS']

# This route will show a form to perform an AJAX request
# jQuery is loaded to execute the request and update the 
# value of the operation

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

#Route that will process the file upload
@app.route('/upload',methods=['POST'])
def upload():
  uploaded_files = request.files.getlist("file[]")
  filenames = []
  for file in uploaded_files:
    if file and allowed_file(file.filename):
      filename = secure_filename(file.filename)
      file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
      filenames.append(filename)

  print uploaded_files

  #RUN BASH SCRIPT HERE.


  return render_template('upload.html',filenames=filenames)

@app.route('/uploads/<filename>')
def uploaded_file(filename):
  return send_from_directory(app.config['UPLOAD_FOLDER'],filename)


if __name__ == '__main__':
  app.run(
    host='0.0.0.0',
    #port=int("80"),
    debug=True
  )

      

Perhaps I was missing a library? I found a similar Q&A on stackoverflow where someone wanted to run a (known) shell command ($ ls -l). My case is different from the fact that it is not a known command, but a generated script:

from flask import Flask
import subprocess

app = Flask(__name__)

@app.route("/")

def hello():
    cmd = ["ls","-l"]
    p = subprocess.Popen(cmd, stdout = subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            stdin=subprocess.PIPE)
    out,err = p.communicate()
    return out
if __name__ == "__main__" :
    app.run()

      

+3


source to share


1 answer


If you want to run matlab, just change your command to

cmd = ["matlab", "-nodisplay", "-nosplash", "-r", "run_image_alg"]

      



If you want to redirect the output to a file:

with open('text_output.txt', 'w') as fout:
    subprocess.Popen(cmd, stdout=fout,
                          stderr=subprocess.PIPE,
                          stdin=subprocess.PIPE)

      

+6


source







All Articles