最近将 Flask 添加到随机打印单词的示例无限循环中。但是,当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
...
Run Code Online (Sandbox Code Playgroud)
我想要的是能够while
在 Flask 应用程序运行时运行循环。
有什么办法可以解决这个问题吗?
要在启动 Flask 服务器之前运行一些代码,现在建议使用应用程序工厂模式。
基本上,这个想法是用app = Flask(__name__)
返回对象的适当函数替换app
。例如,我们可以在我们的__init__.py
:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
# Globally accessible libraries
db = SQLAlchemy()
r = FlaskRedis()
def init_app():
"""Initialize the core application."""
app = Flask(__name__, instance_relative_config=False)
app.config.from_object('config.Config')
# Initialize Plugins
db.init_app(app)
r.init_app(app)
with app.app_context():
# before_first_request equivalent here
# Include our Routes
from . import routes
# Register Blueprints
app.register_blueprint(auth.auth_bp)
app.register_blueprint(admin.admin_bp)
return app
Run Code Online (Sandbox Code Playgroud)
因此,对于之前放入的内容before_first_request
,现在只需将它们放入with app.app_context():
.
然后,在应用程序入口(例如main.py
),我们简单地使用它:
app = init_app()
if __name__ == "__main__":
app.run(host='0.0.0.0')
Run Code Online (Sandbox Code Playgroud)
欲了解更多信息,推荐这篇好文章。
您可以使用before_first_request代替。用 修饰的函数@app.before_first_request
将在第一次请求该应用程序实例之前运行一次。
代码如下所示:
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")
Run Code Online (Sandbox Code Playgroud)
中的代码before_first_request_func
将在第一次向服务器发出请求之前执行一次。因此,启动 Flask 实例后,可以使用curl
so 来模拟对服务器的第一个请求。
您可以使用多线程来做您想做的事情:
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()
Run Code Online (Sandbox Code Playgroud)
输出:
* 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
[...]
Run Code Online (Sandbox Code Playgroud)
这个想法很简单:
您也可以使用多处理而不是多线程来完成此操作:
这里的(主要)区别是这些函数将在不同的 CPU 和内存空间中运行。
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)
Run Code Online (Sandbox Code Playgroud)
如果您想使用before_first_request
@Triet Doan 提出的建议:您必须将 while 函数作为参数传递,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()
Run Code Online (Sandbox Code Playgroud)
在此设置中,将执行 while 函数,并且当它完成时,您的应用程序将运行,但我认为这不是您所要求的?