【问题标题】:Python subprocess callback another py scriptPython子进程回调另一个py脚本
【发布时间】:2021-11-03 14:39:43
【问题描述】:

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

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执行一个函数并将文件导入flask文件。在test.py 中,您只需返回一些内容,然后将其保存在烧瓶路线的变量中。这是你想要达到的目标吗?
  • 你的意思是在主脚本中添加import test.py?
  • 是的@Dmitry 从那里你可以执行类似another.foo() 的操作,然后返回你在​​another.py 文件中定义的结果
  • 你为什么使用子进程? Python 代码一般应该导入其他 Python 代码并调用它,而不是作为单独的进程执行。

标签: python subprocess


【解决方案1】:

假设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/start时process就会启动

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

【讨论】:

    猜你喜欢
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 2015-08-31
    • 1970-01-01
    相关资源
    最近更新 更多