首页 > 解决方案 > 不允许我在服务器仍在执行某些功能时调用 python flask API

问题描述

我正在尝试第一次实现烧瓶客户端服务器架构。

我的服务器代码:

from flask import Flask, request
from Flask.Config import Config

global config

class MyFlaskApp(Flask):
    def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
        if not self.debug or os.getenv('WERKZEUG_RUN_MAIN') == 'true':
            with self.app_context():
                init()
        super(MyFlaskApp, self).run(host=host, port=port, debug=debug, load_dotenv=load_dotenv, **options)


app = MyFlaskApp(__name__)


def init():
    global config
    config = Config()
    config.configure()
    config.execute()


@app.route('/get_results/', methods=['POST'])
def process_request():
    global config
    dict = config.get_dictionary()
    json_object = json.dumps(dict)
    return json_object


if __name__ == "__main__":
    app.run(debug=True, port=5000)

我正在函数中的方法中执行一些连续执行(while True:循环),它会不断更新一些字典。客户端代码调用服务器 API 并获取更新的字典。我的客户代码:config.execute()init()

import requests    

def main():
    response = requests.post("http://127.0.0.1:5000/get_parking_results/").json()

if __name__ == "__main__":
    main()

我首先运行服务器,它执行预期的计算和更新字典。但是当我运行客户端代码时,它给了我以下错误:

requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=5000): Max retries exceeded with url: /get_parking_results/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000020A922D4828>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it',))

但是,如果我config.execute()init()函数中评论,那么它会成功地将字典返回给客户端。基本上,当服务器在 while 循环中连续执行某些操作时,它不允许我向服务器发送请求。为什么会这样?我尝试init()通过一个单独的线程运行函数,它起作用了。如果我不想使用线程怎么办?解决办法是什么?

标签: pythonflaskpython-requests

解决方案


您的代码run() -> init() -> config.execute() -> while True: ...在启动实际服务器之前执行super().run()

您希望您的服务器进程同时做两件事:config.execute()运行服务器以便它可以处理请求。唯一的方法是使用多个线程或进程。

由于您想共享内存中的全局对象,因此多个进程在这里不会轻松工作config,因此最好从线程开始。

这实际上很容易:

import threading

# Under init(), instead of config.execute()
threading.Thread(target=config.execute).start()

没有线程的替代方案是不要尝试同时做多件事。也许不是有一个while True循环,而是可以在返回之前process_request进行一些更新。config

或者您可以将您的架构拆分为完全独立的进程。一个进程不断更新config并将结果存储在数据库或 JSON 文件中,而服务器读取文件而不是拥有全局config变量。


推荐阅读