0

I use subprocess.Popen(['python', 'test.py']) to call another script
How to get callback from another python script to main in Flask?
My code is

from flask import Flask, render_template, request, redirect, url_for
import subprocess

app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'])
def main():

    global process

    if request.method == 'POST':

        index = request.form['index']

        if index == 'start':
            process = subprocess.Popen(['python', 'test.py'])

        if index == 'stop':

            ###
            # after click stop btn i want to get array from another py script
            ###

            process.kill()

        return redirect(url_for('main'))

    return render_template('index.html')

app.run(debug=True)
4
  • you can execute a function from test.py and import the file into the flask file. in the test.py you simply return something which then get's saved in the variable in the flask route. Is that what you want to achieve? Commented Nov 3, 2021 at 14:46
  • you mean add import test.py in main script? Commented Nov 3, 2021 at 14:48
  • yes @Dmitry from there on you can do something like another.foo() which then returns an result you defined in your another.py file Commented Nov 3, 2021 at 14:50
  • Why are you using subprocess? Python code should generally import other Python code and call it, not execute it as a separate process. Commented Nov 18, 2021 at 3:16

1 Answer 1

1

Let's say that test.py file is infinite loop returning current date:

# test.py

from time import sleep
from datetime import datetime

i = 0
while True:
  i += 1
  print(f'"now_{i}": "{datetime.now().strftime("%H-%M-%S")}",')
  sleep(5)

output:

"now_1": "11-48-22",
"now_2": "11-48-27",
"now_3": "11-48-32",
...

Flask application code should be like:

from flask import Flask, render_template, request, redirect, url_for
import subprocess
import signal
import os

app = Flask(__name__)

process = None


def control_proc(action):

  global process

  if action == 'start':
    process = subprocess.Popen(['python', 'test.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    return None
  elif action == 'stop':
   if process is None:
     return b'', b'Run process first'
   else:
     try:
       # if windows
       if os.name == 'nt':
         process.send_signal(signal.CTRL_C_EVENT)
       # if linux
       else:
         process.send_signal(signal.SIGINT)
       return process.communicate(timeout=2)
     except ValueError:
       return b'', b'Looks like process already stopped'
  else:
    raise Exception(f'Bad command: {action}')


@app.route('/', methods=['POST', 'GET'])
def main():
  return '<html><a href="/start">START</a><br><a href="/stop">STOP</a></html>'


@app.route('/start', methods=['GET'])
def start():
  control_proc("start")
  return '{"status": "started"}'

@app.route('/stop', methods=['GET'])
def stop():

  result = control_proc("stop")

  return '{"status": "stopped", "output": {' + result[0].decode("utf-8").rstrip(",\n") + '}' + ', "error": "' + result[1].decode("utf-8").replace('"', '') + '"}'

app.run(debug=True)

When you access http://127.0.0.1:5000/start process will be started

http://127.0.0.1:5000/stop url stop the process and print process output

{
  "status": "stopped",
  "output": {
    "now_1": "11-59-41",
    "now_2": "11-59-46",
    "now_3": "11-59-51",
    "now_4": "11-59-56",
    "now_5": "12-00-01",
    "now_6": "12-00-06",
    "now_7": "12-00-11",
    "now_8": "12-00-16",
    "now_9": "12-00-21",
    "now_10": "12-00-26",
    "now_11": "12-00-31"
  },
  "error": "Traceback (most recent call last): File test.py, line 8, in sleep(5) KeyboardInterrupt "
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.