Незаметно от всех 12 мая 2021 вышла новая версия известного микрофреймворка Flask. Хотя казалось, что во Flask есть уже все, ну или почти все, что нужно для микрофреймворка.
Предвкушая интерес, а что же нового завезли, оставлю ссылку на Change log.
Из приглянувшихся особенностей новой версии:
Прекращена поддержка Python версии 2. Минимальная версия Python 3.6
Поддержка асинхронных view и других обратных вызовов, таких как обработчики ошибок, определенные с помощью async def. Обычные синхронные view продолжают работать без изменений. Функции ASGI, такие как веб-сокеты, не поддерживаются.
Добавьте декораторы роутов для общих методов HTTP API.
@app.post ("/ login") == @ app.route ("/ login", methods = ["POST"])Новая функция Config.from_file для загрузки конфигурации из файла любого формата.
Команда flask shell включает завершение табуляции, как это делает обычная оболочка python.
При обслуживании статических файлов браузеры будут кэшировать на основе содержимого, а не на основе 12-часового таймера. Это означает, что изменения статического содержимого, такого как стили CSS, будут немедленно отражены при перезагрузке без необходимости очистки кеша.
Рассмотрим асинхронность
Все бы было хорошо, но в самом начале после установки был не найден модуль asgiref. Доустановим руками.
Для примера напишем самое простое приложение: Ping/Pong. Оно не имеет особого смысла и сложной логики, только имитирует некоторую проверку "жив ли сервис". Также это приложение станет бенчмарком.
from flask import Flask
app = Flask(__name__)
@app.get('/')
async def ping():
return {'message': 'pong'}
if __name__ == '__main__':
app.run(host='0.0.0.0')
Деплой
Как было сказано в Change log: "Функции ASGI, такие как веб-сокеты, не поддерживаются."
То есть только единственный способ задеплоить приложение используя gunicorn.
Команда: gunicorn -w 8 --bind 0.0.0.0:5000 app:app
-w 8 - 8 запущенных процессов
--bind 0.0.0.0:5000 - адрес приложения
Сверим производительность
Команда для нагрузочного тестирования: wrk -t 8 -c 100 -d 5 http://localhost:5000
Асинхронное приложение Flask 2.0:
Running 5s test @ http://localhost:5000
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 17.80ms 2.37ms 36.95ms 91.92%
Req/Sec 673.44 163.80 3.86k 99.75%
26891 requests in 5.10s, 4.21MB read
Requests/sec: 5273.84
Transfer/sec: 844.69KB
Синхронное приложение Flask 2.0:
Running 5s test @ http://localhost:5000
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.91ms 842.62us 21.56ms 89.86%
Req/Sec 2.38k 410.20 7.64k 93.53%
95301 requests in 5.10s, 14.91MB read
Requests/sec: 18689.25
Transfer/sec: 2.92MB
Синхронное приложение Flask 1.1.2:
Running 5s test @ http://localhost:5000
8 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.98ms 823.42us 17.40ms 88.55%
Req/Sec 2.37k 505.28 12.23k 98.50%
94522 requests in 5.10s, 14.78MB read
Requests/sec: 18537.84
Transfer/sec: 2.90MB
В качестве вывода
Исходя из результатов бенчмарков можно увидеть, что 1 и 2 версия в синхронном режиме выдают одинаковые результаты(с небольшой погрешностью). Что касается асинхронности в Flask 2.0 можно сделать вывод, что пока она слишком сырая даже в dev режиме запуска асинхронный view отстает от синхронного. Но также не стоит забывать о том что ASGI пока не поддерживается, и нет возможности запустить через uvicorn. Остается только ждать обновления и следить за дальнейшим развитием.
Обновилась именно major версия, а это значит у нас есть надежда новую переосмысленную итерацию фреймворка. Разработчиков стоит похвалить как минимум за то, что проект не заброшен и старается успевать за основными тенденциями в других фреймворках. Лично мне очень нравится Flask, он совершенно не перегружен, как например Django.
Если у вас есть идеи, почему получились именно такие результаты - пожалуйста поделитесь ими в комментариях.