英文:
Turbo Flask Multithreading Application Context
问题
我目前正在开发一个Flask Web应用程序,该应用程序在后台线程中持续扫描本地网络,并且我正在使用Turbo Flask来将更新的结果推送到请求的视图中。
一切运行正常,但现在我在尝试使用Flask应用工厂方法将任务拆分到不同模块时遇到了问题:每当扫描线程执行时,我会收到一个 RuntimeError: Working outside of application context
错误,即使在线程函数内部使用 with current_app.app_context():
。
这是我的 __init__.py
文件:
from flask import Flask
from turbo_flask import Turbo
import threading
# 全局库
turbo = Turbo()
def init_app():
# 创建和配置应用程序
app = Flask(__name__, instance_relative_config=False)
app.config.from_object('config.Config')
# 初始化插件
turbo.init_app(app)
with app.app_context():
from . import control
control.ctrl_init(turbo)
@app.before_first_request
def before_first_request():
threading.Thread(target=control.ext_updater).start()
return app
这是我的精简 control.py
文件:
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app
)
from turbo_flask import Turbo
import os, click, requests
import nmap
turbo = Turbo()
def ctrl_init(turboa):
turbo = turboa
def ext_updater():
# 启动线程不断查找外部机器
with current_app.app_context():
while True:
ping_guests()
turbo.push(turbo.replace(render_template("external_machines.html"), 'guests'))
def ping_guests():
# 网络扫描代码被省略
我实际上不确定如何正确启动具有应用程序上下文的线程,而且我猜测将 turbo
对象传递给 ctrl_init
函数也不是一个干净的方式,但我有点迷茫,希望能得到任何帮助!
错误首次出现在 control.ext_updater
中的 with current_app.app_context():
,但删除它后,调用 turbo.push
时仍会引发相同的错误。
英文:
I am currently developing a flask webapp that continuously scans the local network in a background thread and I am using Turbo Flask to push the updated results in a request's view.
Everything works fine but now I am having trouble splitting the tasks in different modules using the flask application factory approach: whenever the scanning thread is executed I get an RuntimeError: Working outside of application context.
even when using with current_app.app_context():
inside the thread function.
Here is my __init__.py
:
from flask import Flask
from turbo_flask import Turbo
import threading
# global libraries
turbo = Turbo()
def init_app():
# create and configure the app
app = Flask(__name__, instance_relative_config=False)
app.config.from_object('config.Config')
# init plugins
turbo.init_app(app)
with app.app_context():
from . import control
control.ctrl_init(turbo)
@app.before_first_request
def before_first_request():
threading.Thread(target=control.ext_updater).start()
return app
And this is my reduced control.py
from flask import (
Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app
)
from turbo_flask import Turbo
import os, click, requests
import nmap
turbo = Turbo()
def ctrl_init(turboa):
turbo = turboa
def ext_updater():
# start thread constantly looking for external machines
with current_app.app_context():
while True:
ping_guests()
turbo.push(turbo.replace(render_template("external_machines.html"), 'guests'))
def ping_guests():
# network scanning code ommited
I'm actually not sure how to properly start the thread with the application context, and I guess passing the turbo
object to the ctrl_init
function is also not a neat way but I'm a little lost here and would appreciate any help!
The error is first thrown at the with current_app.app_context():
in control.ext_updater
but also removing it throws the same error when calling turbo.push
.
答案1
得分: 0
我明白了,我让它能够在创建更新程序线程时传递应用对象:
def ext_updater(app, turbo):
with app.app_context():
while True:
ping_guests()
turbo.push(turbo.replace(render_template("external_machines.html"), 'guests'))
然后使用以下方式调用它:threading.Thread(target=control.ext_updater, args=(app, turbo)).start()
不过,为什么在线程中不能使用current_app
?
英文:
Okay, I got it working passing the app object along with creating the updater thread:
def ext_updater(app, turbo):
with app.app_context():
while True:
ping_guests()
turbo.push(turbo.replace(render_template("external_machines.html"), 'guests'))
And call it with threading.Thread(target=control.ext_updater, args=(app, turbo)).start()
However, why doesn't it work with current_app
in the thread?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论