首页 > 解决方案 > 如何在烧瓶 API Python 中移出 app.run()

问题描述

我正在研究 python 项目,其中包括flask API server单击按钮开始。对于我正在使用的按钮和 UI pyqt5。因此,在启动服务器按钮上单击烧瓶 api 服务器将启动,在停止服务器按钮单击时,烧瓶 api 服务器将停止。

我能够启动服务器,但问题是当我们启动烧瓶 api 服务器时,我们使用app.run(HOST, 80). 在此期间,控件始终保留在此处并且不会移出,因此当我单击停止按钮时,它不会停止。下面是代码:

应用程序.py

import sys
import time
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from server import start_local_server
from PyQt5.QtCore import pyqtSlot
from threading import Thread


run = True


def start_api_server():
    while run:
        start_local_server()
        print("server is running")
    time.sleep(1)
    print("SERVER HAS STOPPED")


class App(QWidget):
    global run

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 button - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 320
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        start_btn = QPushButton('Start Server', self)
        start_btn.move(100, 70)
        start_btn.clicked.connect(self.on_click_start_btn)

        stop_btn = QPushButton('Stop Server', self)
        stop_btn.move(200, 70)
        stop_btn.clicked.connect(self.on_click_stop_btn)

        fun_btn = QPushButton('Click to check responsiveness', self)
        fun_btn.move(150, 100)
        fun_btn.clicked.connect(self.on_click_fun_btn)

        self.show()

    @pyqtSlot()
    def on_click_start_btn(self):
        Thread(target=start_api_server).start()
        
    @pyqtSlot()
    def on_click_stop_btn(self):
        print("Stop server ")
        run = False
        
    @pyqtSlot()
    def on_click_fun_btn(self):
        print('If it is working, this means UI is responsive')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

在上面的代码中,我有按钮单击功能,on_click_start_btn这会启动一个带有 target 的线程start_api_server。这将进一步启动本地烧瓶服务器。当我想停止服务器时,我将简单地设置runFalse哪个会破坏start_api_server功能并且服务器将停止。据我了解,这应该可以正常工作。

以下是烧瓶 api 的代码:

服务器.py

import os
import datetime
from flask import Flask, jsonify
from flask_cors import CORS


app = Flask(__name__)
CORS(app)
wsgi_app = app.wsgi_app


@app.route('/api/status')
def check_status():
    return jsonify({'status': 'ok', 'date': datetime.datetime.now().isoformat()}), 200


def start_local_server():
    HOST = os.environ.get('SERVER_HOST', 'localhost')
    try:
        PORT = int(os.environ.get('SERVER_PORT', '5555'))
    except ValueError:
        PORT = 5555
    app.run(HOST, 80)

问题出现在上面的烧瓶代码中。在上面的代码中,有start_local_server()一个我们正在使用的函数app.py。在这个我们有app.run(),当我们的代码到达这里时,它总是保留在这里并且永远不会移出它,因此我无法停止这个服务器。

我想简单地编写代码,我可以使用按钮单击启动和停止烧瓶服务器,但由于app.run,它不起作用。谁能帮我解决这个问题。是否有任何替代上述问题。请帮忙。谢谢

根据答案更新代码:

server = Process

def start_local_server():
    global server
    server = Process(target=app.run, args=('localhost', 80))
    # HOST = os.environ.get('SERVER_HOST', 'localhost')
    # try:
    #     PORT = int(os.environ.get('SERVER_PORT', '5555'))
    # except ValueError:
    #     PORT = 5555
    # app.run(HOST, 80)


def stop_local_server():
    global server
    server.terminate()

标签: pythonflaskpyqt5

解决方案


您可以app.run()单独运行Process。多处理对您的情况会有所帮助,因为您使用的是 pyQt。

from multiprocessing import Process

server = Process(target=app.run, args=(HOST, 80))
server.start() # to start the server
server.terminate() # to terminate the server

您可以在此处更深入地查看multiprocessing库文档https://docs.python.org/2/library/multiprocessing.html

你忘了启动服务器:)

server = None

def start_local_server():
    global server
    server = Process(target=app.run, args=('localhost', 80))
    server.start()
    # HOST = os.environ.get('SERVER_HOST', 'localhost')
    # try:
    #     PORT = int(os.environ.get('SERVER_PORT', '5555'))
    # except ValueError:
    #     PORT = 5555
    # app.run(HOST, 80)


def stop_local_server():
    global server
    server.terminate()

推荐阅读