Zen of Python
19.2K subscribers
1.35K photos
202 videos
38 files
3.45K links
Полный Дзен Пайтона в одном канале

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Сайт: https://tprg.ru/site

Регистрация в перечне РКН: https://tprg.ru/xZOL
Download Telegram
aiohttp выпустил 3.14.0 — крупный минорный релиз асинхронного HTTP-клиента и сервера. Упор на типобезопасность и быструю работу с JSON.

Что внутри:
🔘 типобезопасные ключи контекста RequestKey и ResponseKey вместо строковых ключей в request[...] — промах по типу теперь ловит чекер, а не прод;
🔘 работа с JSON прямо в байтах: json_bytes_response и send_json_bytes отдают уже сериализованные байты, без лишнего прохода через строку;
🔘 в WebSocket появился decode_text — получить TEXT-фрейм сразу как bytes и скормить его, например, orjson;
🔘 encode_basic_auth для аккуратной сборки заголовка Basic-аутентификации;
🔘 cleanup-контексты приложения теперь умеют асинхронные менеджеры контекста.

Если держите сервисы на aiohttp, апгрейд бесплатно даёт и более строгие типы, и меньше накладных расходов на JSON под нагрузкой.

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Появился PEP 835, который предлагает сократить запись Annotated. Если пишете на Pydantic, FastAPI, Typer или SQLModel, вы видели это каждый день:

id: Annotated[int, Field(gt=0)]
name: Annotated[str, Field(min_length=3)]


PEP предлагает оператор @ для метаданных типа:

id: int @ Field(gt=0)
name: str @ Field(min_length=3)


Та же Annotated, просто запись короче.

Детали из предложения:
🔘@ связывает сильнее, чем |: запись int | str @ Meta читается как int | Annotated[str, Meta], а для объединения с метаданными нужны скобки (int | str) @ Meta;
🔘цепочка T @ m1 @ m2 разворачивается в плоскую Annotated[T, m1, m2], без вложенности;
🔘под капотом появляется встроенный тип types.AnnotatedType на C, а typing.Annotated станет ссылкой на него;
🔘старая форма Annotated[X, Y] никуда не денется, остаётся для совместимости.

Сокращение нацелено на Python 3.16, до этого его можно будет пробовать через typing_extensions.

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
👍171
FastAPI выкатил два релиза подряд, 0.137.0 и 0.138.0, и оба меняют привычные вещи. Самое заметное снаружи появилось в 0.138.0: метод app.frontend().

Теперь собранный фронтенд раздаётся прямо из FastAPI, без отдельного nginx или статик-сервера:

app.frontend("/", directory="dist")


Кладёте билд SPA в dist, одна строка, и приложение само отдаёт его на корне. Есть и router.frontend() для поддерева.

Под капотом в 0.137.0 переписали то, как роутеры включаются друг в друга:
🔘раньше include_router() клонировал каждый путь в один плоский список, и в итоге на всё приложение оставался один роутер;
🔘теперь исходные объекты APIRouter и APIRoute сохраняются, а router.routes стал деревом промежуточных объектов;
🔘из-за этого маршруты можно добавлять в подроутер уже после include_router(), изменения подхватятся, потому что роуты не копируются;
🔘в части случаев это ещё и экономит память.

Здесь же спрятан ломающий момент: если ваш код ходил по router.routes как по плоскому списку APIRoute, он сломается, теперь это дерево. Для таких сценариев в 0.137.2 добавили iter_route_contexts().

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤‍🔥2
На python.org можно было войти как админ с любым API-ключом

Если в API python.org подсунуть имя администратора и произвольный ключ, система пропускала запрос с правами администратора. Никакого перебора, никакой магии — просто имя пользователя и левый ключ.

При этом атакующий не мог переписать сами файлы, но мог поменять URL для скачивания каждого релиза и ссылки на проверочные материалы Sigstore и PGP. Python Insider пишет, что баг пролежал в коде с 2014 года. Корпоративный перевод: «мы не трогаем бинари, мы только подменяем, куда вы их качаете».

Команда безопасности Python получила отчёт 23 февраля и закрыла уязвимость менее чем за 48 часов. Артефакты проверили по подписям, следов вмешательства не нашли. Сайт уже пропатчен.
👀1
Виктор Стиннер, один из ключевых разработчиков CPython, разобрал в блоге, как устроен PyMutex, замок размером в один байт, на котором держится free-threaded Python.

Зачем такой маленький? В режиме без GIL блокировка нужна на каждый объект отдельно: свой замок у каждого dict, list, set. Старый замок через py_recursivelock_t занимает 72 байта. Для сравнения, пустой список в Python 3.13 весит 56 байт, пустой словарь 64. Вешать по 72 байта на каждый объект невозможно. PyMutex решает это: один байт, из которого реально используются два бита под состояния (свободен, занят, занят с ожидающими потоками).

Что показали замеры. Дизайн взят из WebKit, у их движка есть WTF::Lock, а под капотом лежит _PyParkingLot, кроссплатформенный аналог futex. На захвате и освобождении без конкуренции:
🔘Linux x86-64: PyMutex 11 нс против 44 нс у старого замка, в 4 раза быстрее;
🔘macOS arm64: 13 нс против 18 нс, в 1,4 раза;
🔘Windows x86-64: 13 нс против 38 нс, в 2,9 раза.

Оговорка для авторов C-расширений: напрямую PyMutex использовать не стоит, легко словить взаимоблокировку. Для защиты доступа к объектам есть critical section API, Py_BEGIN_CRITICAL_SECTION(obj).

@zen_of_python
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43
⚡️ AI-инструменты можно любить и ненавидеть, но работать без них в IT уже практически невозможно!

Коллеги из AvitoTech 11 июля зовут в их офис на Лесной на AI Hardcore Day. Приглашают тех, кто каждый день сталкивается с AI в работе и даже пишет своих AI-агентов. Обещают доклады и нетворкинг-сессию на террасе после — и всё это без записи.

✔️ Среди тем:
— Spec-Driven Development: теория, инструменты, практика;
— Разработка и тестирование MCP для внутренних агентных систем аналитики;
— Выпрямляем руки агентов: как сделать MCP удобными и действительно полезными;
— Атаки на GenAI-агентов: OWASP на практике.

➡️ Регистрация тут!

Это #партнёрский пост
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
time.sleep() — не везде правильный способ подождать

В синхронном скрипте time.sleep(2.5) идиоматичен: пауза в текущем потоке, никаких сюрпризов. Но в отдельном потоке ту же паузу не прервать по сигналу: лучше threading.Event().wait(), который просыпается по event.set().

В асинхронном коде time.sleep() заморозит весь event loop, потому что корутина не уступает управление. Правильный инструмент: await asyncio.sleep(), он приостанавливает только текущую задачу.

В гайде
ещё про декоратор retry, rate limit и паузы в GUI через root.after().
👍10
Forwarded from IT Юмор
😭4
Отправка почты из Python: stdlib, локальный SMTP и сторонние библиотеки

В стандартной библиотеке Python для работы с почтой есть пакет email и модуль для SMTP-соединений: формируете сообщение, добавляете вложения и адресатов, подключаетесь к серверу и отправляете. Для отладки удобно поднять локальный SMTP-сервер — письма не уйдут в интернет, но вы увидите, как они собираются.

Явное лучше неявного, но ручная сборка писем со временем утомляет. Статья разбирает сторонние инструменты вроде Yagmail и transactional email-сервисов, чтобы вы могли выбрать между «всё под контролем» и готовым решением.

Кому полезно: тем, кто отправляет уведомления, рассылки или отчёты из Python и хочет сравнить подходы.
👌3
Pathway — Python-фреймворк для потоковой обработки данных на Rust-движке

Pathway даёт писать на Python пайплайны реального времени: чтение из источника, преобразования, запись в приёмник, а тяжёлая часть считается Rust-движком. Тот же код работает и на пакетных данных, и на бесконечном потоке. Релиз v0.31.1 вышел 12 июня, на GitHub больше 62 тысяч звёзд.

Этот релиз почти целиком про новые коннекторы к базам:
🔘pw.io.elasticsearch.read читает индекс Elasticsearch: своего механизма отслеживания изменений у него нет, поэтому коннектор опрашивает и сверяет пересечение соседних запросов, чтобы ни одна строка не потерялась и не пришла дважды;
🔘pw.io.clickhouse.write пишет в ClickHouse по нативному протоколу, в двух режимах: поток изменений с колонками time и diff либо снапшот текущего состояния в ReplacingMergeTree;
🔘pw.io.mysql.read делает полноценный захват изменений через бинлог MySQL: сначала снимок таблицы, потом непрерывная доставка вставок, обновлений и удалений;
🔘расширили чтение Iceberg, теперь декодируются все примитивные типы, включая date, time, uuid, fixed и decimal;
🔘у коннекторов Postgres добавили набор проверок на старте, чтобы кривая конфигурация падала понятной ошибкой ещё до молчаливой потери строк.

Пригодится дата-инженерам, которые строят аналитику и ETL реального времени и устали склеивать поток из десятка разных коннекторов вручную.

https://github.com/pathwaycom/pathway

Язык: Python и Rust. Лицензия: BSL-1.1.

@prog_tools
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯1
Где держать Telegram-бота или API, чтобы они не падали под нагрузкой и не съедали бюджет?

Tproger собрал подборку из шести VPS-провайдеров под этот сценарий: от тарифов за пару сотен рублей в месяц до конфигураций с DDR5 и портом 10 Гбит/с. У каждого свой акцент — где-то посуточная оплата и запуск за минуту, где-то API для CI/CD, бэкапы и приватные сети, где-то зарубежные локации.

Внутри по каждому провайдеру: реальные конфигурации, цены, на какой нагрузке тестировали и под какой сценарий брать.

https://tproger.ru/articles/gde-razvernut-bota-ili-api---podborka-vps--kotorye-ne-tormozyat