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

Асинхронное программирование теперь является первоклассным гражданином в Python. Если вы веб-разработчик, вы можете выбрать топ-5 изумительных фреймворков.

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

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

Но достаточно мотивации!

Давайте рассмотрим некоторые из лучших асинхронных фреймворков на Python.

1. Tornado

Tornado

Удивительно, но Торнадо не является новым фреймворком. Его первый выпуск был в 2009 году (ровно десять лет назад, на момент написания статьи), и с тех пор он сосредоточился на обеспечении надежного асинхронного программирования с высокой степенью параллелизма.

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

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

Они были объединены для получения окончательных каркасных модулей: tornado.webtornado.routingtornado.templateи т.д.

import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")
def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])
if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Tornado имеет сильных и преданных последователей в сообществе Python и используется опытными архитекторами для создания высокопроизводительных систем. Это фреймворк, который долгое время отвечал на проблемы параллелизма, но, возможно, не стал мейнстримом, поскольку не поддерживает стандарт WSGI и был слишком активным участником (помните, что большинство библиотек Python по-прежнему синхронны ).

2. Sanic

Sanic

Sanic — это «современный» фреймворк, который не поддерживает версию Python ниже 3.6. Поддерживает простой и универсальный синтаксис async / await «из коробки» и, как следствие, не заставляет вас читать множество документации и помните о крайних случаях, прежде чем вы сможете написать свой первый обработчик HTTP.

Синтаксис в Sanic довольно приятен. Он напоминает код, который вы бы написали с помощью любой другой микросхемы (например, Flask, CherryPy), добавив всего несколько async:

from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
    return json({"hello": "world"})
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Sanic, пожалуй, самая популярная асинхронная среда в мире Python. Он имеет почти все функции, необходимые для множества проектов — маршрутизация, промежуточное ПО, файлы cookie, управление версиями, чертежи, представления на основе классов, статические файлы, потоковая передача, сокеты и то, что он не предлагает «из коробки». — шаблонизатор, поддержка базы данных, файловый ввод / вывод, очереди и т.д.

3. Vibora

Vibora

Vibora — близкий родственник Sanic, за исключением того, что он намерен стать самым быстрым веб-сервером Python.

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

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

from vibora import Vibora, JsonResponse
app = Vibora()
@app.route('/')
async def home():
    return JsonResponse({'hello': 'world'})
if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000)

  На момент написания статьи Vibora подвергается полной переписке, чтобы стать еще быстрее, и ссылка на ее версию для исполнения говорит о том, что она находится в стадии «тяжелой разработки».  

4. Quart

Quart

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

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

from quart import Quart
app = Quart(__name__)
@app.route('/')
async def hello():
    return 'hello'
app.run()

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

5. FastAPI

FastAPI

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

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

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

from fastapi import FastAPI
app = FastAPI()
@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

Заключение

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

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