简体   繁体   English

How to excecute code after Flask `app.run()` statement (run a Flask app and a function in parallel, execute code while Flask server is running)

[英]How to excecute code after Flask `app.run()` statement (run a Flask app and a function in parallel, execute code while Flask server is running)

Recently added Flask to a sample infinite-loop which randomly prints words.最近将 Flask 添加到随机打印单词的示例无限循环中。 However, when adding app.run(host='0.0.0.0') the code after that line won't execute after I stop Flask running.但是,当添加app.run(host='0.0.0.0')时,在我停止 Flask 运行后,该行之后的代码将不会执行。

if __name__ == '__main__':
    app.run(host='0.0.0.0')

    while True:  # won't run until I press stop once (stop Flask) when running directly from IDE
        ...

What I want is to be able to run the while loop while the Flask app is running.我想要的是能够在 Flask 应用程序运行时运行while循环。

Is there any way to solve this?有没有办法解决这个问题?

You can use before_first_request instead.您可以改用before_first_request Functions decorated with @app.before_first_request will run once before the first request to this instance of the application.@app.before_first_request修饰的函数将在对应用程序实例的第一个请求之前运行一次。

The code looks like this:代码如下所示:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    print("index is running!")
    return "Hello world"

@app.before_first_request
def before_first_request_func():
    print("This function will run once")


if __name__ == "__main__":
    app.run(host="0.0.0.0")

The code in before_first_request_func will be executed once before the first request to the server. before_first_request_func中的代码将在第一次向服务器请求之前执行一次。 Therefore, after starting the Flask instance, one can simulate the first request to the server using curl or so.因此,启动Flask实例后,可以模拟使用curl左右对服务器的第一个请求。

You can do what you want by using multithreading:您可以使用多线程来做您想做的事:

from flask import Flask
import threading
import time

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello, World!"

def run_app():
    app.run(debug=False, threaded=True)

def while_function():
    i = 0
    while i < 20:
        time.sleep(1)
        print(i)
        i += 1

if __name__ == "__main__":
    first_thread = threading.Thread(target=run_app)
    second_thread = threading.Thread(target=while_function)
    first_thread.start()
    second_thread.start()

Output: Output:

 * Serving Flask app "app"
 * Environment: production
 * Debug mode: off
 * Running on [...] (Press CTRL+C to quit)
0
1
2
3
4
5
6
7
8
[...]

The idea is simple:这个想法很简单:

  • create 2 functions, one to run the app and an other to execute the wile loop,创建 2 个函数,一个用于运行应用程序,另一个用于执行 wile 循环,
  • and then execute each function in a seperate thread, making them run in parallel然后在单独的线程中执行每个 function ,使它们并行运行

You can do this with multiprocessing instead of multithreading too:您也可以使用多处理而不是多线程来做到这一点:

The (main) differences here is that the functions will run on different CPUs and in memory spaces.这里的(主要)区别在于这些函数将在不同的 CPU 和 memory 空间中运行。

from flask import Flask
from multiprocessing import Process
import time

# Helper function to easly  parallelize multiple functions
def parallelize_functions(*functions):
    processes = []
    for function in functions:
        p = Process(target=function)
        p.start()
        processes.append(p)
    for p in processes:
        p.join()

# The function that will run in parallel with the Flask app
def while_function():
    i = 0
    while i < 20:
        time.sleep(1)
        print(i)
        i += 1

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "Hello, World!"

def run_app():
    app.run(debug=False)

if __name__ == '__main__':
    parallelize_functions(while_function, run_app)

If you want to use before_first_request proposed by @Triet Doan : you will have to pass the while function as an argument of before_first_request like this:如果您想使用 @Triet Doan 提出的before_first_request :您必须将 while function 作为before_first_request的参数传递,如下所示:

from flask import Flask
import time

app = Flask(__name__)

def while_function(arg):
    i = 0
    while i < 5:
        time.sleep(1)
        print(i)
        i += 1

@app.before_first_request(while_function)
@app.route("/")
def index():
    print("index is running!")
    return "Hello world"

if __name__ == "__main__":
    app.run()

In this setup, the while function will be executed, and, when it will be finished, your app will run, but I don't think that was what you were asking for?在此设置中,将执行 while function ,并且当它完成时,您的应用程序将运行,但我认为这不是您所要求的?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM