Python programming
April 30, 2020

Топ 5 асинхронных веб-фреймворков на Python

Асинхронность уже не является просто модным словечком в сообществе Python. После выпуска библиотеки asyncio в версии 3.5, разработчики Python признали влияние Node.js в сфере веб-разработки и ввели в язык два новых ключевых слова – async и await. Это был крайне важный момент, потому что разработчики максимально осторожно относятся к расширению основного синтаксиса, если только нет острой необходимости, что только указывает на то, насколько принципиально необходимыми считались асинхронные возможности.

В результате перед асинхронностью открылись новые границы: новые и старые библиотеки начали использовать функционал корутин, асинхронные фреймворки взорвались популярностью, а на сегодняшний день пишут всё больше и больше новых модулей. Производительность наравне (или даже лучше) c Node.js уже не является чем-то необычным. И нет никаких причин, из-за которых вы не могли бы делать тысячи запросов в секунду, если ваш код не создаёт высокие нагрузки на процессор.

Пожалуй, хватит мотивации. Давайте лучше глянем на текущую ситуацию в Python и рассмотрим некоторые из лучших асинхронных фреймворков.


Tornado

На удивление, Tornado – достаточно старый фреймворк. Самый первый релиз был выпущен ещё в далёком 2009 году (более десяти лет назад), и сейчас его основное внимание направлено на обеспечении надежного асинхронного программирования с высоким параллелизмом.

Tornado изначально не являлся веб-фреймворком. На самом деле это просто набор асинхронных модулей, которые используются для построения модулей веб-фреймворка. Если более конкретно, то вот эти модули:

  • Корутины и другие примитивы (tornado.gen, tornado.locks, tornado.queues и т. д.)
  • Сетевые модули (tornado.ioloop, tornado.iostream и т. д.)
  • Асинхронные сервера и клиенты (tornado.httpserver, tornado.httpclient и т. д.)

Они были совмещены для получения финальный модулей фреймворка: tornado.web, tornado.routing, tornado.template и тому подобные.

Tornado имеет сильную и преданную поддержку в сообществе Python и используется опытными архитекторами для создания высокоэффективных систем. Это фреймворк, который уже давно имеет ответ на проблемы параллелизма, но не стал мейнстримом, поскольку он не поддерживает стандарт WSGI. А также важно помнить, что основная часть библиотек Python всё ещё синхронна.

Sanic

Sanic – это "современный" фреймворк в прямом смысле слова: он не работает в Python ниже версии 3.6, поддерживает синтаксис async/await из коробки, и как следствие, это не заставляет вас читать кучу документации и держать в голове все крайние случаи, прежде чем вы сможете написать свой первый обработчик.

В результате получившийся синтаксис довольно приятен; он напоминает код, который вы написали бы на любом другом микрофреймворке (например, Flask, CherryPy) просто с несколькими асинхронными вставками:

Sanic, пожалуй, является самым популярным и наиболе понравившемся сообществу асинхронным фреймворков в мире Python. Он имеет практически весь функционал, который вам понадобился бы для проекта – маршрутизация, middleware, куки, контроль версий, блупринты, представления на основе классов, статические файлы, streaming, сокеты и многое другое. А то, что он не предоставляет из коробки – шаблоны, поддержка баз данных, I/O операции с файлами, очереди – вы можете добавить сами, так как существует уже достаточно асинхронных библиотек для всего, что душа пожелает.

Vibora

Фреймворк Vibora крайне похож на Sanic, за исключением того, что он претендует на звание самого быстрого веб-сервера на Python. Более того, при самом первом посещении официального сайта можно увидеть график сравнения с другими фреймворками:

Как вы можете видеть, Vibora заявляет, что она в несколько раз быстрее классических фреймворков и более чем в два раза быстрее Sanic, своего ближайшего конкурента. Конечно, бенчмарки не всегда могут быть объективными показателями. 🙂

Хотя по синтаксису и функциям Vibora сравнима с Sanic (или, возможно, даже немного лучше, поскольку она объединяет популярные библиотеки и такие вещи, как шаблоны, доступные из коробки), я бы счел Sanic более зрелым, поскольку он существует дольше и имеет более обширное сообщество.

Но если вы помешаны на производительности, то Vibora может дать вам большие возможности. Тем не менее, на момент написания статьи Vibora кардинально переписывается, чтобы стать ещё быстрее, и ссылка на страницу про производительность говорит нам о том, что фреймворк находится под “тяжелой разработкой". Однако не спешите выбирать Vibora для своих проектов, иначе вы рано или поздно столкнётесь с критическими изменениями. Но всё-таки это только начало асинхронного мира Python, и не следует ожидать чего-либо железно стабильного.

Quart

Если вам приятно разрабатывать на Flask, но не хватает асинхронной поддержки, то вам определнно понравится Quart.

Quart соответствует стандарту ASGI, который является преемником знаменитого стандарта WSGI и предлагает асинхронную поддержку. Самое интересное в Quart то, что он не только похож на Flask, но и фактически совместим с Flask API! Автор этого фреймворка хотел сохранить ощущение работы с Flask и просто добавить к нему поддержку асинхронности, WebSockets и HTTP 2. В результате вы можете изучить Quart прямо по документации Flask'а, просто имея в виду, что функции в Quart являются асинхронными.

Выглядит (почти) как Flask, разве не так?

Поскольку Quart – это эволюция Flask, то и весь функционал из Flask также доступен: маршрутизация, middleware, сессии, шаблоны, блупринты и так далее. Более того, вы даже можете использовать расширения Flask непосредственно внутри Quart. Загвоздка заключается лишь в том, что поддерживается Python только версии 3.7+, но если вы не используете последнюю версию Python, то и использовать асинхронность имеет мало смысла. 🙂

Документация действительно нужна, если у вас нет предварительного опыта работы с Flask, но я могу всё-таки рекомендовать Quart, поскольку это, вероятно, единственный асинхронный фреймворк, который скоро выйдет в версии 1.0.

FastAPI

Последним (но самым впечатляющим) фреймворком в этом списке является FastAPI. Нет, это не только API-фреймворк; на самом деле FastAPI, похоже, является самым многофункциональным и богатым документацией фреймворком, с которым я столкнулся при исследовании асинхронных фреймворков в Python.

Интересно, что автор фреймворка глубоко изучил несколько других фреймворков, от классических, таких как Django, до более современных, таких как Sanic, а также изучил различные технологии в NestJS (веб-фреймворк Node.js, Typescript). Про их философию развития и масштабные сравнения можно прочитать здесь.

Синтаксис довольно приятный; можно даже утверждать, что он гораздо приятнее, чем другие фреймворки, с которыми мы сталкивались:

А теперь представлю список убийственных функций, которые заставляют FastAPI затмевать другие фреймворки:

API автоматической генерации документации: как только ваши конечные точки будут реализованы, вы сможете поиграться с API, используя соответствующий стандартам пользовательский интерфейс. Поддерживаются SwaggerUI, ReDoc и другие.

Фреймворк также создаёт автоматическую документацию для моделей в JSON формате.

Современное развитие: да, слово "современный" часто бросается в глаза, но именно в контексте FastAPI оно уместно. Внедрение зависимостей и аннотация типов – это объекты первого класса, не только позволяющие применять хорошие принципы программирования, но и предотвращающие ошибки и путаницу в долгосрочной перспективе.

Обширная документация: не знаю насчёт вас, но я большой любитель хорошей документации. И в этой области FastAPI преуспел лучше других. В нем есть страницы за страницами документации, объясняющие почти каждую тонкость и моменты, в которых нужно быть осторожным, для разработчиков всех уровней. Сразу видно, что в такую документацию вложили сердце и душу. И единственное сравнение, которое можно найти, – это документация Django (да, документация FastAPI настолько хороша).

Помимо всего прочего: FastAPI поддерживает WebSockets, Streaming, а также GraphQL, помимо того, что у него есть все традиционные функции, такие как CORS, сессии, куки и многие другие.

А как насчет производительности? FastAPI построен на удивительной библиотеке Starlette, в результате чего производительность сравнима — с Node.js, а в некоторых случаях даже Go! В целом, у меня сложилось стойкое предчуствие, что FastAPI будет мчаться вперёд как лучший асинхронный фреймворк для Python.

Заключение

В наши дни очень много событий происходит в асинхронном мире Python. Появляются новые фреймворки, старые переписываются, а библиотеки эволюционируют, чтобы соответствовать асинхронным концепциям. Несмотря на то, что Python имеет встроенную поддержку событийного цикла и можно сделать части вашего приложения асинхронными, у вас всё ещё есть отличная возможность пойти ва-банк и построить приложение на одном из вышеперечисленных фреймворков. Просто не забывайте о долгосрочной перспективе: некоторые из существующих асинхронных фреймворков Python находятся на ранних стадиях и быстро развиваются, что может повредить вашему процессу разработки и повысить бизнес-затраты. Главное – осторожность!

Но все сказано и сделано; Python готов к продакшну и может обеспечить хорошую производительность, когда речь заходит о веб-фреймворках. Если вы долго думали о переходе на Node.js, то теперь вам этого не требуется! 🙂