我为我的python应用程序编写了一个Web界面。运行export FLASK_APP=main.py
后跟flask run
时,此功能非常出色。现在我希望实际的应用程序也运行,因此界面可能很有用。
下面的代码是我的main.py,我在其中调用了flask应用程序工厂函数。
from webinterface import create_app
if __name__ == '__main__':
create_app()
while(True):
# Some code logging different things
我想在无限循环中做一些事情,但是当我尝试运行应用程序时,它只运行web界面或infinte循环,这取决于我是使用flask run
还是{{1}启动它}。
我如何才能最好地完成这项工作?
答案 0 :(得分:0)
在前台应用程序的线程中运行Flask是可能的,有时也很方便。有一个技巧,一个很大的陷阱,一个约束。
约束条件是这是你想要在" safe"中做的事情。环境(例如,在您的笔记本电脑上为本地浏览器提供服务,或在您的家庭内部网上),因为它涉及运行开发服务器,这是您不想在恶劣环境中进行的操作。您也无法使用自动页面重新加载(但您可以启用调试)。
缺点是,如果UI与前台应用程序共享任何非平凡状态(包括dicts),您将需要使用共享threading.Lock()
来保护访问权限,以便只有一个线程在一时间正在读取或写入数据。
诀窍是在创建应用程序的配置之后但在启动它之前将共享状态的引用注入到应用程序的配置中,执行以下操作:
def webserver(state):
app.config['STATE'] = state
# If running on, say, a Raspberry Pi, use 0.0.0.0 so that
# you can connect to the web server from your intranet.
app.run(host='0.0.0.0', use_reloader=False, debug=True)
def main():
state = SharedState()
web_thread = threading.Thread(target=webserver, args=(state,))
web_thread.start()
state.set('counter' 0)
while True:
# Do whatever you want in the foreground thread
state.set('counter', state.get('counter') + 1)
class SharedState():
def __init__(self):
self.lock = threading.Lock()
self.state = dict()
def get(self, key):
with self.lock:
return self.state.get(key)
def set(self, key, value):
with self.lock:
self.state[key] = value
然后,在Flask视图函数中,执行类似
的操作@app.route('/')
def home():
state = app.config['STATE']
counter = state.get(counter)
return render_template("index.html", counter=counter)