从 Quart 中的另一个任务访问 app_context
Access app_context from another task in Quart
我的 Quart 应用程序是使用 create_app 工厂方法创建的。
我还通过 create_task 方法将第三方库合并为一项附加任务。
我将一个回调函数传递给这个更新我的数据库的库(通过 SQLAlchemy)。
不幸的是,这不起作用并引发异常:
"Attempt to access app outside of a relevant context"
推送应用上下文不起作用:
from quart import current_app as app
async with app.app_context():
查看 Quarts 上下文文档:https://pgjones.gitlab.io/quart/contexts.html
原因很明显,因为第三方任务中不存在该应用程序。
Both of these contexts exist per request and allow the global proxies
current_app, request, etc… to be resolved. Note that these contexts
are task local, and hence will not exist if a task is spawned by
ensure_future or create_task.
有没有人有任何其他解决方案来从另一个任务获取应用程序上下文?
编辑
还是不行。我正在使用 Quart 0.10.0。
我的应用程序的更详细示例如下所示:
from app import create_app
from third_party import ThirdParty
third_party = ThirdParty(loop=asyncio.get_event_loop())
app = create_app()
@app.before_serving
async def startup():
async with app.app_context() as app_context:
await third_party.start()
@app.after_serving
async def shutdown():
await third_party.stop()
if __name__ == "__main__":
app.run()
第三方基本上是这样的:
class ThirdParty:
async def start(self):
self.loop.create_task(self.run())
async def run(self):
while True:
await self.wait_for_trigger()
# executes my callback function
await self.custom_callback_func()
我的回调函数在另一个模块中,我传递给 third_party 实例:
from quart import current_app as app
async def custom_callback_func():
async with app.app_context:
# update_my database
# raises "Attempt to access app outside of a relevant context"
如果 app_context 自动从具有应用程序上下文的任务复制到创建的任务,为什么我的示例不起作用?
await third_party.start() 在 with app_context 语句中调用 loop.create_task(运行()) 运行 是我指定的回调函数。那么为什么这个回调里面没有app_context呢?
我想你一定是在使用 0.6.X 版本的 Quart?如果是这样,copy_current_app_context
(来自 quart.ctx)可用于明确地将上下文复制到新任务中。例如,
task = asyncio.ensure_future(copy_current_app_context(other_task_function)())
另见 this short documentation snippet。请注意,它是用 Quart >= 0.7 编写的,它应该会自动复制任务之间的上下文。
编辑:
在更新问题后。
我认为你最好传递 app
实例并直接使用它,而不是在任务中使用 current_app
。这是因为在 before_serving
之后和第一个请求之前没有应用上下文。不过,这在 Quart 中可能会发生变化,请参阅此 issue.
我的 Quart 应用程序是使用 create_app 工厂方法创建的。
我还通过 create_task 方法将第三方库合并为一项附加任务。
我将一个回调函数传递给这个更新我的数据库的库(通过 SQLAlchemy)。 不幸的是,这不起作用并引发异常:
"Attempt to access app outside of a relevant context"
推送应用上下文不起作用:
from quart import current_app as app
async with app.app_context():
查看 Quarts 上下文文档:https://pgjones.gitlab.io/quart/contexts.html 原因很明显,因为第三方任务中不存在该应用程序。
Both of these contexts exist per request and allow the global proxies current_app, request, etc… to be resolved. Note that these contexts are task local, and hence will not exist if a task is spawned by ensure_future or create_task.
有没有人有任何其他解决方案来从另一个任务获取应用程序上下文?
编辑 还是不行。我正在使用 Quart 0.10.0。 我的应用程序的更详细示例如下所示:
from app import create_app
from third_party import ThirdParty
third_party = ThirdParty(loop=asyncio.get_event_loop())
app = create_app()
@app.before_serving
async def startup():
async with app.app_context() as app_context:
await third_party.start()
@app.after_serving
async def shutdown():
await third_party.stop()
if __name__ == "__main__":
app.run()
第三方基本上是这样的:
class ThirdParty:
async def start(self):
self.loop.create_task(self.run())
async def run(self):
while True:
await self.wait_for_trigger()
# executes my callback function
await self.custom_callback_func()
我的回调函数在另一个模块中,我传递给 third_party 实例:
from quart import current_app as app
async def custom_callback_func():
async with app.app_context:
# update_my database
# raises "Attempt to access app outside of a relevant context"
如果 app_context 自动从具有应用程序上下文的任务复制到创建的任务,为什么我的示例不起作用?
await third_party.start() 在 with app_context 语句中调用 loop.create_task(运行()) 运行 是我指定的回调函数。那么为什么这个回调里面没有app_context呢?
我想你一定是在使用 0.6.X 版本的 Quart?如果是这样,copy_current_app_context
(来自 quart.ctx)可用于明确地将上下文复制到新任务中。例如,
task = asyncio.ensure_future(copy_current_app_context(other_task_function)())
另见 this short documentation snippet。请注意,它是用 Quart >= 0.7 编写的,它应该会自动复制任务之间的上下文。
编辑: 在更新问题后。
我认为你最好传递 app
实例并直接使用它,而不是在任务中使用 current_app
。这是因为在 before_serving
之后和第一个请求之前没有应用上下文。不过,这在 Quart 中可能会发生变化,请参阅此 issue.