从 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.