Python 子进程回调另一个 py 脚本

Python subprocess callback another py script

我用subprocess.Popen(['python', 'test.py'])调用另一个脚本
如何从另一个 python 脚本回调到 Flask 中的主程序?
我的代码是

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)

假设 test.py 文件是无限循环返回当前日期:

# 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)

输出:

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

Flask 应用程序代码应如下所示:

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)

当您访问http://127.0.0.1:5000/startprocess将启动

http://127.0.0.1:5000/stop url 停止 process 并打印 process 输出

{
  "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 "
}