python - 与 Flask 应用程序一起运行代码
问题描述
我为我的 python 应用程序编写了一个 Web 界面。这在运行时运行良好,export FLASK_APP=main.py
然后是flask run
. 现在我希望实际的应用程序也能运行,这样界面就会很有用。
下面的代码是我的 main.py,我在其中调用了烧瓶应用程序工厂函数。
from webinterface import create_app
if __name__ == '__main__':
create_app()
while(True):
# Some code logging different things
我想在无限循环中做一些事情,但是当我尝试运行应用程序时,它要么只运行 Web 界面,要么运行无限循环,这取决于我是否使用flask run
或启动它python main.py
。
我怎样才能最好地做到这一点?
解决方案
在前台应用程序的线程中运行 Flask 是可能的,有时也很方便。有一个技巧,一个大陷阱和一个约束。
限制是,这是您希望在“安全”环境中执行的操作(例如,在您的笔记本电脑上为本地浏览器提供服务器,或在您的家庭 Intranet 上),因为它涉及运行开发服务器,而您不这样做不想在充满敌意的环境中工作。您也不能使用自动页面重新加载(但您可以启用调试)。
陷阱在于,如果 UI 与前台应用程序共享任何重要的状态(包括字典),您将需要使用共享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)
推荐阅读
- graph - 流氓图的支配树
- directx - DX11 三角形列表根本不渲染
- flutter - Flutter TextButton splashColor 属性
- file - 在 Go 中读取/写入文件的正确方法
- angular - 对 ngx-formly 自定义模板进行单元测试
- c++ - 在 libstdc++.so 中缺少 GLIBCXX 的 Alpine Linux 库
- c++ - 无法打开包含文件:'stddef.h':在 cstddef QtCreator 中没有这样的文件或目录
- java - 将数据库字段的值与字符串进行比较
- azure-active-directory - 通过 SSO (SAML) 为来自 Internet 的任何用户(不仅仅是公司用户)登录
- python - python 3.8 或 3.8+ 中函数的一般签名是什么?