Доступ к app_context из другой задачи в Quart - PullRequest
0 голосов
/ 19 января 2020

Приложение My Quart создается с помощью метода фабрики create_app.

У меня также есть сторонняя библиотека, включенная в качестве дополнительной задачи через метод create_task.

Я передаю функцию обратного вызова этому библиотека, которая обновляет мою базу данных (через SQLAlchemy). К сожалению, это не работает и вызывает исключение:

«Попытка получить доступ к приложению вне соответствующего контекста»

Выдвижение контекста приложения не работает:

from quart import current_app as app

async with app.app_context():

Глядя на контекстную документацию Quarts: https://pgjones.gitlab.io/quart/contexts.html очевидно, почему, поскольку приложение не существует в третьем задача участника.

Оба этих контекста существуют для каждого запроса и позволяют разрешать глобальные прокси current_app, request и т. д.…. Обратите внимание, что эти контексты являются локальными для задачи, и, следовательно, не будут существовать, если задача порождается sure_future или 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()

ThirdParty в основном таков:

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 вызывает l oop .create_task (run ()), который запускает мою назначенную функцию обратного вызова. Так почему же внутри этого обратного вызова нет app_context?

1 Ответ

0 голосов
/ 19 января 2020

Я думаю, что вы используете версию Quart 0.6.X? В этом случае copy_current_app_context (из quart.ctx) можно использовать для явного копирования контекста в новую задачу. Например,

task = asyncio.ensure_future(copy_current_app_context(other_task_function)())

См. Также этот короткий фрагмент документации . Обратите внимание, что он написан с Quart> = 0.7, который должен автоматически копировать контекст между задачами.

Редактировать: После обновления вопроса.

Я думаю, что вы Лучше всего передать экземпляр app и использовать его напрямую, а не current_app в задаче. Это связано с тем, что после before_serving и до первого запроса отсутствует контекст приложения. Это может измениться в Quart, хотя, смотрите этот выпуск .

...