Топ-5 асинхронних веб-фреймворків для Python

Асинхронне програмування зараз є громадянином першого класу в Python. Якщо ви веб-розробник, у вас є чудові фреймворки, які ви можете вибрати!

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

У результаті відкрилися шлюзи для асинхронного програмування: нові та старі бібліотеки почали використовувати функцію співпрограм, популярність асинхронних фреймворків вибухнула, а нові пишуться й сьогодні. Продуктивність на рівні або вище, ніж у Node.js, не є чимось нечуваним, і якщо ваші шаблони завантаження не передбачають великої кількості важких завдань на ЦП, немає причин, чому ви не можете робити кілька тисяч запитів на секунду.

Але достатньо мотивації!

Давайте дослідимо поточний ландшафт Python і перевіримо деякі з найкращих асинхронних фреймворків.

Торнадо

Дивно, Торнадо це зовсім не нова структура. Його перший випуск був випущений у 2009 році (рівно десять років тому, на момент написання), і з того часу він зосереджувався на забезпеченні надійного асинхронного програмування з високим рівнем паралелізму.

Tornado принципово не є веб-фреймворком. Це набір асинхронних модулів, які також використовуються для створення модуля веб-платформи. Зокрема, ці модулі:

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

Вони були об’єднані для створення остаточних модулів каркаса: tornado.web, tornado.routing, tornado.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 все ще є синхронними ).

  Як відкрити мобільні вкладки Chrome на робочому столі

Санік

Санік є «сучасним» фреймворком у прямому сенсі цього слова: він не підтримує версію Python нижче 3.6, підтримує простий і універсальний синтаксис async/await із коробки, і, як наслідок, не змушує вас читати завантаження документації та пам’ятайте про крайні випадки, перш ніж написати свій перший обробник HTTP.

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

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, керування версіями, креслення, перегляди на основі класів, статичні файли, потокове передавання, сокети тощо — і те, що він не пропонує з коробки. — шаблони, підтримка бази даних, файловий ввід/вивід, черги — можна додати, оскільки на сьогодні для них достатньо асинхронних бібліотек.

Вибора

Вибора є близьким кузеном 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 може стати вашим човном на воді. Тим не менш, на момент написання статті Vibora повністю перезаписує, щоб стати ще швидшою, і посилання до його продуктивної версії сказано, що вона знаходиться на стадії «інтенсивної розробки». Це буде розчарування для тих, хто взяв Vibora раніше, і невдовзі доведеться зіткнутися з кардинальними змінами, але привіт, у світі асинхронізації Python настали перші дні, і ніхто не очікує, що все буде стабільно.

  Як обійти обмеження Wi-Fi у школі (робочі рішення на 2020 рік)

кварта

Якщо вам подобається розробляти у Flask, але шкодуєте про відсутність асинхронної підтримки, вам це сподобається кварта багато.

Кварт відповідає вимогам ASGI стандарт, який є наступником відомого стандарту WSGI і пропонує підтримку асинхронного режиму. Цікава річ про Quart полягає в тому, що він не тільки схожий на Flask, але й фактично сумісний із Flask API! Автор цього фреймворку хотів зберегти відчуття Flask і просто додати до нього підтримку async, WebSockets і HTTP 2. Як результат, ви можете вивчити Quart прямо з документації Flask, просто пам’ятаючи, що функції в Quart є асинхронними.

from quart import Quart

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

app.run()

На відчуття (майже) точно так само, як у Flask, чи не так?!

Оскільки Quart є еволюцією Flask, усі функції Flask доступні: маршрутизація, проміжне ПЗ, сеанси, шаблони, креслення тощо. Фактично, ви навіть можете використовувати розширення Flask безпосередньо в Quart. Одна заковика полягає в тому, що підтримується лише Python 3.7+, але якщо ви використовуєте не останню версію Python, можливо, async — це не правильний шлях. 🙂

Документація дуже потрібна, якщо у вас немає попереднього досвіду роботи з Flask, але я можу порекомендувати Quart, оскільки це, ймовірно, єдиний асинхронний фреймворк, який незабаром наближається до випуску 1.0.

FastAPI

Останній (але найбільш вражаючий) фреймворк у цьому списку FastAPI. Ні, це не фреймворк лише для API; Фактично, FastAPI здається найбагатшим на функції та документацію фреймворком, який я зустрів під час дослідження асинхронних фреймворків Python.

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

Синтаксис досить приємний; можна навіть стверджувати, що це набагато приємніше, ніж інші фреймворки, з якими ми стикалися:

rom 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}

А тепер список вбивчих функцій, завдяки яким FastAPI затьмарює інші фреймворки:

  Відтворюйте відео через Chromecast і передавайте аудіо через свій ПК або Mac

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

Фреймворк також виконує автоматичне документування моделі даних за допомогою схеми JSON.

Сучасна розробка: так, слово «сучасний» часто використовують, але я вважаю, що FastAPI насправді говорить про це. Впровадження залежностей і підказка типів є першокласними громадянами, які забезпечують не тільки хороші принципи кодування, але й запобігають помилкам і плутанині в довгостроковій перспективі.

Розширена документація: я не знаю, як ви, але я взагалі не люблю хорошу документацію. І в цій області FastAPI безперечно перемагає. Він містить сторінки за сторінками документів, які пояснюють майже кожну дрібницю та «увага!» моменти для розробників усіх рівнів. Я відчуваю чітке «серце і душу» в документах тут, і єдине порівняння, яке я можу знайти, це документи Django (так, документи FastAPI такі хороші!).

Окрім основ: FastAPI підтримує WebSockets, Streaming, а також GraphQL, окрім усіх традиційних помічників, таких як CORS, сеанси, файли cookie тощо.

А як щодо продуктивності? Що ж, FastAPI побудовано на дивовижній бібліотеці Starlette, завдяки чому продуктивність відповідає Node, а в деяких випадках навіть Go! Загалом, у мене справді є відчуття, що FastAPI буде мчати вперед як найкраща асинхронна структура для Python.

Висновок

Сьогодні багато чого відбувається в асинхронному ландшафті Python. З’являються нові фреймворки, старі переписуються, а бібліотеки розвиваються відповідно до асинхронної поведінки. Хоча в Python є вбудована підтримка циклу подій і можна зробити частини вашої програми асинхронними, ви можете вибрати загальний варіант і створити одну з фреймворків тут. Просто пам’ятайте про довгострокову перспективу: кілька асинхронних фреймворків Python знаходяться на ранніх стадіях і швидко розвиваються, що зашкодить вашому процесу розробки та підвищить витрати на бізнес. Обережність – головне!

Але все сказано і зроблено; Python готовий до виробництва, щоб забезпечити низьку продуктивність, коли йдеться про веб-фреймворки. Якщо ви так довго думали перейти на Node, тепер вам це не потрібно! 🙂

Звучить круто? Опануйте Python сьогодні!