Spec-Zone.ru › Flask

Использование async и await

Журнал изменений

Добавлена в версии 2.0.

Маршруты, обработчики ошибок, функции до запроса, после запроса и завершения могут быть функциями корутин, если Flask установлен с дополнительным пакетом async (pip install flask[async]). Это позволяет определять представления с 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 с greenlet

При использовании gevent или eventlet для запуска приложения или модификации среды выполнения требуется greenlet>=1.0. При использовании PyPy требуется PyPy>=7.3.7.

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

Асинхронные функции требуют цикла событий для работы. Flask, как WSGI-приложение, использует одного работника для обработки одного цикла запроса/ответа. Когда запрос поступает в асинхронное представление, Flask запустит цикл событий в потоке, выполнит функцию представления там, а затем вернёт результат.

Каждый запрос по-прежнему связывает одного работника, даже для асинхронных представлений. Преимущество заключается в том, что вы можете выполнять асинхронный код внутри представления, например, для выполнения нескольких одновременных баз данных, запросов к внешнему API и т. д. Однако количество запросов, которые ваше приложение может обрабатывать одновременно, останется прежним.

Асинхронный код не обязательно быстрее синхронного. Асинхронность полезна при выполнении одновременных задач, связанных с вводом-выводом, но, вероятно, не улучшит задачи, связанные с ЦП. Традиционные представления Flask по-прежнему будут подходить для большинства случаев использования, но асинхронная поддержка Flask позволяет писать и использовать код, который раньше было невозможно написать.

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

Асинхронные функции будут выполняться в цикле событий до завершения, после чего цикл событий остановится. Это означает, что любые дополнительные задачи, которые не были завершены к моменту завершения асинхронной функции, будут отменены. Поэтому вы не можете запускать фоновые задачи, например, с помощью asyncio.create_task.

Если вы хотите использовать фоновые задачи, лучше всего использовать очередь задач для запуска фоновой работы, а не запускать задачи в функции представления. С учетом этого, вы можете запускать задачи asyncio, используя ASGI-сервер для запуска Flask и используя адаптер asgiref WsgiToAsgi, как описано в ASGI. Это работает, так как адаптер создаёт цикл событий, который постоянно работает.

Когда использовать Quart вместо Flask

Асинхронная поддержка Flask менее производительна, чем фреймворки, ориентированные на асинхронный код, из-за способа её реализации. Если у вас преимущественно асинхронный код, стоит рассмотреть Quart. Quart — это повторная реализация Flask, основанная на стандарте ASGI вместо WSGI. Это позволяет ему обрабатывать множество одновременных запросов, длительные запросы и веб-сокеты без необходимости в нескольких рабочих процессах или потоках.

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

Расширения

Расширения Flask, предшествующие асинхронной поддержке Flask, не ожидают асинхронных представлений. Если они предоставляют декораторы для добавления функциональности к представлениям, они, вероятно, не будут работать с асинхронными представлениями, потому что они не будут ожидать выполнения функции или не будут ожидаемыми. Другие предоставляемые функции также не будут ожидаемыми и, вероятно, будут блокирующими, если их вызывать внутри асинхронного представления.

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

def extension(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        ...  # Extension logic
        return current_app.ensure_sync(func)(*args, **kwargs)

    return wrapper

Проверьте журнал изменений расширения, которое вы хотите использовать, чтобы узнать, реализовали ли они асинхронную поддержку, или отправьте запрос на добавление функции или PR.

Другие циклы событий

В настоящее время Flask поддерживает только asyncio. Возможно переопределить flask.Flask.ensure_sync(), чтобы изменить способ обертывания асинхронных функций для использования другой библиотеки.

© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/stable/async-await/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API