Rapidy - новый web-фреимворк на базе aiohttp
Недавно заметил, что в чатиках разгоняют про ещё один новый web-фреимворк, только уже построенный на aiohttp. Зачем, конечно, в 2025 году использовать aiohttp - вопрос сложный, но автор отвечает на него так - это для любителей aiohttp. Ну раз так, то ладно.
Вообще, когда я писал сервисы на aiohttp, мне всегда хотелось иметь работу с pydantic как у FastAPI. Можно сказать, автор воплотил одну из моих идей.
Что под капотом из того, что мне приглянулось?
- Валидация и сериализация как в хендлерах, так и в middleware при помощи полюбившегося всем Pydantic.
- Нативная интеграция с dishka.
- Декларативные контроллеры в виде классов с наследованием параметров - вкусовщина ещё та, но мне нравится:
- Ну и по стандарту, всё что уже и так есть в aiohttp.
А обещают нам:
- Генерацию OpenAPI - очень хотелось бы видеть.
- HTTP клиент обмазанный Pydantic - видимо чтобы быстренько клепать интеграции с http-сервисами.
- И, самое интересное - поддержку GRPC. Вот тут очень стало интересно, как это будет выглядеть.
Всё это, конечно, звучит круто, но у фреимворка есть самый большой недостаток, который вытекает из самого aiohttp - нету asgi. Мне кажется, что если его исправить, то ему можно будет даже подвинуться между легким FastAPI и уже ставшим монструозным Litestar.
Поэтому, пока что для меня - это aiohttp на стероидах. Удобный, легкий, слегка фичастый, подведенный к стандарту разработки 2025 года.
Github | Документация
#библиотека
Недавно заметил, что в чатиках разгоняют про ещё один новый web-фреимворк, только уже построенный на aiohttp. Зачем, конечно, в 2025 году использовать aiohttp - вопрос сложный, но автор отвечает на него так - это для любителей aiohttp. Ну раз так, то ладно.
Вообще, когда я писал сервисы на aiohttp, мне всегда хотелось иметь работу с pydantic как у FastAPI. Можно сказать, автор воплотил одну из моих идей.
Что под капотом из того, что мне приглянулось?
- Валидация и сериализация как в хендлерах, так и в middleware при помощи полюбившегося всем Pydantic.
- Нативная интеграция с dishka.
- Декларативные контроллеры в виде классов с наследованием параметров - вкусовщина ещё та, но мне нравится:
@controller('/')
class UserController:
@get('/{user_id}')
async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]:
return {'user_id': user_id}
@get()
async def get_all_users(self) -> list[dict[str, str]]:
return [{'name': 'John'}, {'name': 'Felix'}]
- Ну и по стандарту, всё что уже и так есть в aiohttp.
А обещают нам:
- Генерацию OpenAPI - очень хотелось бы видеть.
- HTTP клиент обмазанный Pydantic - видимо чтобы быстренько клепать интеграции с http-сервисами.
- И, самое интересное - поддержку GRPC. Вот тут очень стало интересно, как это будет выглядеть.
Всё это, конечно, звучит круто, но у фреимворка есть самый большой недостаток, который вытекает из самого aiohttp - нету asgi. Мне кажется, что если его исправить, то ему можно будет даже подвинуться между легким FastAPI и уже ставшим монструозным Litestar.
Поэтому, пока что для меня - это aiohttp на стероидах. Удобный, легкий, слегка фичастый, подведенный к стандарту разработки 2025 года.
Github | Документация
#библиотека
🔥9❤5👏3
Помните про такую старинную питонячью забаву - гуй/фронтенд через Python рисовать?
Я даже пару постов делал об этом (тык, тык) - но все эти инструменты были "ну такие". Где-то фатальный недостаток в архитектуре, где-то кнопки мне не понравились.
В основном это нужно для людей, которые от фронтенда достаточно далеки - ML-щики, аналитики и датасотонисты, например. Я их понимаю, не осуждаю. Вот и ребята из Snowflake поняли, не осудили и придумали... Streamlit!
Что есть внутри:
- Простая генерация веб-интерфейса - на скриншоте можете увидеть, как просто делается интерфейс в принципе.
- Элементы - интерактивные! Чекбоксы, слайдеры, поля для ввода, таблички - здесь есть всё, что может понадобиться!
- Умеет отображать не только обычные списочки/словари, а еще датафреймы pandas, графики altair, bokeh, numpy и кучу еще всего!
- Очень простое API для создания собственных компонентов.
- Умеет в Markdown и Latex.
Поэтому, если хотите MVP прототип наклепать или написать очередной внутренний инструмент, продемонстрировать ML-модель - можно пользоваться!
А еще плейграунд есть - можно прям в браузере попробовать!
P.S. В комментах подсказали, что Streamlit сначала был отдельным проектом, а уже Snowflake его потом купили.
Github | Сайт | PyPi (39 тыщ звёзд!)
#библиотека
Я даже пару постов делал об этом (тык, тык) - но все эти инструменты были "ну такие". Где-то фатальный недостаток в архитектуре, где-то кнопки мне не понравились.
В основном это нужно для людей, которые от фронтенда достаточно далеки - ML-щики, аналитики и датасотонисты, например. Я их понимаю, не осуждаю. Вот и ребята из Snowflake поняли, не осудили и придумали... Streamlit!
Что есть внутри:
- Простая генерация веб-интерфейса - на скриншоте можете увидеть, как просто делается интерфейс в принципе.
- Элементы - интерактивные! Чекбоксы, слайдеры, поля для ввода, таблички - здесь есть всё, что может понадобиться!
- Умеет отображать не только обычные списочки/словари, а еще датафреймы pandas, графики altair, bokeh, numpy и кучу еще всего!
- Очень простое API для создания собственных компонентов.
- Умеет в Markdown и Latex.
Поэтому, если хотите MVP прототип наклепать или написать очередной внутренний инструмент, продемонстрировать ML-модель - можно пользоваться!
А еще плейграунд есть - можно прям в браузере попробовать!
P.S. В комментах подсказали, что Streamlit сначала был отдельным проектом, а уже Snowflake его потом купили.
Github | Сайт | PyPi (39 тыщ звёзд!)
#библиотека
🔥8👏4❤1
niquests - молодой преемник requests
Долгое-долгое время всеми нами любимая библиотека request для http запросов была де-факто стандартом.
Но время шло, в питоне появилось нормальное асинхронное программирование, технологии развивались, а requests никак не адаптировался к изменениям - у них там гордый feature freeze.
Когда у меинтейнеров спрашивали, как там насчёт асинка, видите ли, requests - это "feature-complete piece of software at this time", да и вообще есть весомые причины.
Вот так и жили. Сначала появился aiohttp. Потом httpx, который стал очень популярным и совместил несколько подходов, сразу в одном клиенте.
А потом появился наш парень niquests (первый релиз с 29 августа 2023 года), форк requests, который начал решать проблемы своего отца:
- Наконец появился асинк!
- Появилась поддержка HTTP/2 и HTTP/3 over QUIC (которой НЕТ даже в httpx/aiohttp!)
- Тредсейф, для любителей потоков
- Мультиплексирование соединения
- Добавили поддержку DNSSEC (этого нет ни в requests, ни в httpx ни в aiohttp).
- Есть DNS over HTTPS/QUIC/TLS - этого тоже нет в конкурентах
- Работа с вебсокетами (есть только в aiohttp и то только HTTP/1), и SSE (этого ни у кого нет).
- Ну и аннотации типов (с 3.0.0), хранение сертификатов в памяти и так далее - мы же не в прошлом десятилетии живём.
Да куча, блин, фич! Можете тут взглянуть на табличку, я не всё перечислил.
Вы думаете это всё? Он рвёт своих конкурентов по скорости - примерно в 3 раза быстрее в тестах - смотрите скриншот.
Самое, блин, грустное - я практически не вижу его в опенсурсных проектах. Но на бумаге выглядит очень круто.
Что думаете? Пользовались ли? Сможет ли он отнять часть рыночка? Пишите в комментарии, обсудим!
Github | Документация | PyPi
#библиотека
Долгое-долгое время всеми нами любимая библиотека request для http запросов была де-факто стандартом.
Но время шло, в питоне появилось нормальное асинхронное программирование, технологии развивались, а requests никак не адаптировался к изменениям - у них там гордый feature freeze.
Когда у меинтейнеров спрашивали, как там насчёт асинка, видите ли, requests - это "feature-complete piece of software at this time", да и вообще есть весомые причины.
Вот так и жили. Сначала появился aiohttp. Потом httpx, который стал очень популярным и совместил несколько подходов, сразу в одном клиенте.
А потом появился наш парень niquests (первый релиз с 29 августа 2023 года), форк requests, который начал решать проблемы своего отца:
- Наконец появился асинк!
- Появилась поддержка HTTP/2 и HTTP/3 over QUIC (которой НЕТ даже в httpx/aiohttp!)
- Тредсейф, для любителей потоков
- Мультиплексирование соединения
- Добавили поддержку DNSSEC (этого нет ни в requests, ни в httpx ни в aiohttp).
- Есть DNS over HTTPS/QUIC/TLS - этого тоже нет в конкурентах
- Работа с вебсокетами (есть только в aiohttp и то только HTTP/1), и SSE (этого ни у кого нет).
- Ну и аннотации типов (с 3.0.0), хранение сертификатов в памяти и так далее - мы же не в прошлом десятилетии живём.
Да куча, блин, фич! Можете тут взглянуть на табличку, я не всё перечислил.
Вы думаете это всё? Он рвёт своих конкурентов по скорости - примерно в 3 раза быстрее в тестах - смотрите скриншот.
Самое, блин, грустное - я практически не вижу его в опенсурсных проектах. Но на бумаге выглядит очень круто.
Что думаете? Пользовались ли? Сможет ли он отнять часть рыночка? Пишите в комментарии, обсудим!
Github | Документация | PyPi
#библиотека
🔥21
def process(x: str | int) -> None:
if isinstance(x, int):
do_for_int(x)
elif isinstance(x, str):
do_for_str(x)
public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; }
public String add(String a) { return a; }
1. В стандартной библиотеке есть есть functools.singledispatch и functools.singledispatchmethod, но корректно они работают только с 1 аргументом
from functools import singledispatch
@singledispatch
def process(x: Any):
print(f"Общий случай: {x}")
@process.register
def _(x: str):
print(f"Строка: {x}")
@process.register
def _(x: str, y: int): # сработает, но и сломает предыдущий обработчик
print(f"{x=}, {y=}")
2. Одно время часто советовали multipledispatch, но у него ряд недостатков - его не любят IDE, тайпинги не поддерживает, да и вообще всё еще стремно выглядит
from multipledispatch import dispatch
@dispatch(int, int) # никаких тайп хинтов, только вот так
def add(x, y):
return x + y
@dispatch(object, object)
def add(x, y):
return f"{x} + {y}"
add(1, 2) # 3
add(1, 'hello') #'1 + hello'
3. А еще можно использовать ovld
list[tuple[str, int])
А теперь небольшой примерчик:
from ovld import ovld
@ovld
def f(x: str):
return f"Строка {x!r}"
@ovld
def f(x: int):
return f"Число {x}"
@ovld
def f(x: int, y: int):
return "Джва числа!"
Ну красиво же? Я уже молчу при всякие фичи в виде кодгена, миксинов, метакласса который проставляет декоратор как бы за вас, типов зависимых по значению (есть проверка текста по регуляркам) и еще много всего!
GitHub | Документация | PyPi
#библиотека
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - mrocklin/multipledispatch: Multiple dispatch
Multiple dispatch. Contribute to mrocklin/multipledispatch development by creating an account on GitHub.
🎉13🔥8❤4
Еще у меня встречался кейс, когда есть какая-то штука, которая ставится на сервер, у которой нет API но есть CLI-утилита. Вот такие библиотеки здорово выручают.
В последний раз, кстати, я такую штуку использовал для того, чтобы выкачивать бекапы. Был только доступен SFTP, поэтому мы выживали как могли...
Однажды я участвовал в одной CTF, в одной из тасок надо было за 5 команд получить доступ к флагу.
Количество попыток было ограничено. Угадаете, на чем было реализовано?
Документация | Github | PyPi
#библиотека
Please open Telegram to view this post
VIEW IN TELEGRAM
👏6🔥3🤔3❤1
class Action[ReqT, RespT](Protocol):
name: str
request_schema: Type[ReqT] # тип который мы будем принимать
response_schema: Type[RespT] # тип который мы будем возвращать
interact: Callable[[ReqT], Coroutine[Any, Any, RespT]]
def create_action_handler(action: Action):
# какой-то код
async def action_endpoint(entity_id: int, data: dict[str, Any]) -> Any:
# какой-то код
return await action.interact(server, data)
return action_endpoint
def add_action_route(router: APIRouter, action: Action):
handler = create_action_handler(action)
router.post(
f"/plugins/{action.name}",
response_model=action.response_schema, # установим схему для ответа
)(handler)
Схему для ответа я установил при регистрации нашего эндпоинта в
response_model
. А что делать с data
, тип которого должен быть не dict[str, Any]
а action.request_schema
handler = create_action_handler(action)
handler.__annotations__["data"] = action.request_schema
Но это не помогло - аннотации поменялись, а вот схема - нет
Зная это нам остается только одно - изменить signature перед регистрацией роута
sig = inspect.signature(handler) # достаем сигнатуру
new = []
for p in sig.parameters.values():
if p.name == "data": # находим нашу data
p = p.replace(annotation=action.request_schema) # меняем
new.append(p)
handler.__signature__ = sig.replace(parameters=new) # записываем новую сигнатуру
Вуаля! Теперь в OpenAPI будет указанная в
action.request_schema
схема #fastapi #рецепт
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯4🔥3