Сообщить об ошибке.

Использование async и await в приложении на Flask.

Маршруты, обработчики ошибок, функции до и после запроса, а также функции освобождения ресурсов могут быть функциями сопрограмм, если Flask установлен с дополнительным параметром async (pip install flask [async]). Для этого требуется Python 3.7+, где доступен contextvars.ContextVar. Это позволяет определять представления с помощью async def и использовать await.

Синтаксис:

@app.route("/get-data")
async def get_data():
    data = await async_db_query(...)
    return jsonify(data)
Подключаемые представления на основе классов также поддерживают обработчики, реализованные как сопрограммы. Это относится к методу dispatch_request() в представлениях, которые наследуются от класса flask.views.View, а также ко всем обработчикам методов HTTP в представлениях, которые наследуются от класса flask.views.MethodView.

Использование async в Windows на Python 3.8

В Windows в Python 3.8 есть ошибка, связанная с модулем asyncio. Если столкнетесь с чем-то вроде ValueError: set_wakeup_fd, то обновите Python до версии 3.9.

Производительность

Для асинхронных функций требуется цикл событий. Фреймворк Flask, как приложение WSGI, использует одну задачу/воркер для обработки одного цикла запроса/ответа. Когда запрос поступает в асинхронное представление, то Flask запускает цикл обработки событий в отдельном потоке, запускает там функцию представление, а затем возвращает результат.
Каждый запрос по-прежнему связывает одну задачу, даже для асинхронных представлений. Положительным моментом является то, что асинхронный код можно запускать в самом представлении, например, для выполнения нескольких одновременных запросов к базе данных и/или HTTP-запросов к внешнему API и т. д. НО количество запросов, которые веб-приложение может обрабатывать одновременно, останется прежним.
Использование async def по своей сути не быстрее, чем синхронный код. Асинхронный режим полезен при выполнении параллельных задач, связанных с вводом-выводом, но, вероятно, не улучшит задачи, связанные с процессором. Традиционные представления Flask по-прежнему подходят для большинства случаев использования, но поддержка async в Flask позволяет писать и использовать код, что раньше было невозможно изначально.

Фоновые задачи

Асинхронные функции будут выполняться в цикле событий до тех пор, пока они не завершатся, после чего этот цикл событий остановится. Это означает, что любые дополнительные порожденные задачи, которые не были выполнены после завершения асинхронной функции, будут отменены. Поэтому нельзя запускать фоновые задачи, например, через asyncio.create_task.
Если необходимо использовать фоновые задачи, то лучше всего использовать очередь задач для запуска фоновой работы, а не создавать задачи в функции-представлении. Принимая сказанное во внимание, можно запускать задачи asyncio, обслуживая Flask с сервером ASGI и используя адаптер WsgiToAsgi, как описано в ASGI. Так как адаптер создаст непрерывный цикл обработки событий, то это точно будет работать.
Например:
Адаптер WsgiToAsgi интегрируется с циклом событий, используемым для Flask. Что бы использовать адаптер, необходимо обернуть приложение Flask:
from asgiref.wsgi import WsgiToAsgi
from flask import Flask

app = Flask(__name__)

...

asgi_app = WsgiToAsgi(app)
а затем запускать приложение asgi_app с сервером asgi, например, с помощью Hypercorn.
$ hypercorn module:asgi_app

Когда использовать асинхронный фреймворк Quart

Поддержка async в Flask менее эффективна, чем фреймворки, которые изначально разрабатывались как async-first из-за способа реализации асинхронности. Если у вас в основном асинхронная кодовая база, то имеет смысл рассмотреть использования модуля Quart. Фреймворк Quart - это точная реализация Flask, основанная на стандарте ASGI вместо WSGI. Такая реализация позволяет ему обрабатывать множество одновременных запросов, длительных запросов и веб-сокетов, не требуя нескольких процессов или потоков.
Также можно запустить Flask с Gevent или Eventlet, для достижения преимущества обработки асинхронных запросов. Эти библиотеки исправляют низкоуровневые функции Python для достижения цели асинхронной обработки. Решение о том, следует ли использовать Flask, Quart или что-то еще, зависит от понимания конкретных потребностей разрабатываемого веб-проекта.

Расширения Flask и асинхронность.

Расширения Flask, написанные до поддержки async во Flask, не предполагают асинхронных представлений. Если они предоставляют декораторы для добавления функциональности к представлениям, то они не будут работать с асинхронными представлениями, потому что они не будут ожидать функцию или быть ожидаемыми. Другие функции, которые они предоставляют, также не будут ожидаемыми и, вероятно, будут блокироваться при вызове в асинхронном представлении.
Авторы расширений могут поддерживать асинхронные функции, используя [метод flask.Flask.ensure_sync(). Например, если расширение предоставляет декоратор для функции-представления, то необходимо добавить app.ensure_sync() перед вызовом функции-декоратора.