Статья «Building a CI/CD Pipeline Runner from Scratch in Python»
Автор показал, как собрать с нуля свой мини‑раннер для CI/CD на Python для случаев без доступа к GitHub Actions/GitLab Runner, чтобы понять, что происходит под капотом и запускать пайплайны в изолированных окружениях без облака. Ключевая идея простая: раннер — это оркестратор, который парсит YAML, строит граф зависимостей, запускает задачи в контейнерах, стримит логи и пробрасывает артефакты между задачами.
Из примеров: классика со стадиями build/test/deploy, где build кладёт сборку в dist/, тесты берут контент из dist/ и запускаются параллельно, а деплой на прод запускается только в ветке main. Артефакты складываются во внутреннюю .pipeline_artifacts и перед каждым шагом подтягиваются по списку нужных задач, при этом рабочая папка монтируется в контейнер, а команды шага объединяются в одну строку shell.
Такой раннер пригодится для локального теста конфигов или учебных задач, когда хочется гибкости без внешних сервисов. До продакшен уровня остаются распределённое выполнение, кеши зависимостей, матричные сборки, секреты, сервис‑контейнеры и ретраи, но базовая архитектура — парсер, планировщик, исполнитель и менеджер артефактов — уже закрывает основные потребности.
@zen_of_python
Автор показал, как собрать с нуля свой мини‑раннер для CI/CD на Python для случаев без доступа к GitHub Actions/GitLab Runner, чтобы понять, что происходит под капотом и запускать пайплайны в изолированных окружениях без облака. Ключевая идея простая: раннер — это оркестратор, который парсит YAML, строит граф зависимостей, запускает задачи в контейнерах, стримит логи и пробрасывает артефакты между задачами.
Из примеров: классика со стадиями build/test/deploy, где build кладёт сборку в dist/, тесты берут контент из dist/ и запускаются параллельно, а деплой на прод запускается только в ветке main. Артефакты складываются во внутреннюю .pipeline_artifacts и перед каждым шагом подтягиваются по списку нужных задач, при этом рабочая папка монтируется в контейнер, а команды шага объединяются в одну строку shell.
Такой раннер пригодится для локального теста конфигов или учебных задач, когда хочется гибкости без внешних сервисов. До продакшен уровня остаются распределённое выполнение, кеши зависимостей, матричные сборки, секреты, сервис‑контейнеры и ретраи, но базовая архитектура — парсер, планировщик, исполнитель и менеджер артефактов — уже закрывает основные потребности.
@zen_of_python
⚡3
Forwarded from Типичный программист
С кем знакомятся типичные программисты: 2D-тян или живая девушка?
Согласно недавним исследованиям Vantage Point Counseling Services, треть американцев хотя бы раз состояла в романтических отношениях с ИИ. Появилось даже приложение Loverse для виртуальных знакомств, где вместо реальных людей роль партнёров выполняют чат-боты с искусственным интеллектом.
Мы решили провести своё исследование и выяснить где и с кем сегодня знакомятся пользователи стран СНГ. Пожалуйста, пройдите наш небольшой опрос. Это поможет нашему исследованию.
Пройти опрос.
Согласно недавним исследованиям Vantage Point Counseling Services, треть американцев хотя бы раз состояла в романтических отношениях с ИИ. Появилось даже приложение Loverse для виртуальных знакомств, где вместо реальных людей роль партнёров выполняют чат-боты с искусственным интеллектом.
Мы решили провести своё исследование и выяснить где и с кем сегодня знакомятся пользователи стран СНГ. Пожалуйста, пройдите наш небольшой опрос. Это поможет нашему исследованию.
Пройти опрос.
❤4😢1
Вы знали, что у нас есть канал с хитрыми задачками по Python?
Вот прямо сейчас там в комментариях обсуждаем задачу с подвохом.
Каждый рабочий день по одной задачке с квизом, можно сразу проверить себя. И через час пост с подробным объяснением, почему именно так.
Вот прямо сейчас там в комментариях обсуждаем задачу с подвохом.
Каждый рабочий день по одной задачке с квизом, можно сразу проверить себя. И через час пост с подробным объяснением, почему именно так.
🗿5
Занятный проект на Python из категории «потому что могу»: Rubiksolver
Коротко: это десктоп-приложение, которое через веб-камеру считывает состояние перемешанного кубика Рубика и показывает пошаговое решение с анимацией в окне на PySide6 с отрисовкой через OpenGL и обработкой изображения в OpenCV. Проект позиционируется как учебный — подойдёт тем, кто хочет понять базовые приёмы компьютерного зрения и графики на практике.
Сканирование: показываете камере по одной грани по заранее заданным правилам. После скана жмёте Play, чтобы запустить анимацию, или листаете шаги кнопками Previous/Next — так удобно проверять, что распознание и сама сборка идут корректно.
Установка: клонируете репозиторий, выполняете
Автор отмечает, что на Android встречаются решалки, но чаще всего там состояние кубика приходится вбивать руками, без автосканирования камерой — здесь как раз закрыта эта боль.
@zen_of_python
Коротко: это десктоп-приложение, которое через веб-камеру считывает состояние перемешанного кубика Рубика и показывает пошаговое решение с анимацией в окне на PySide6 с отрисовкой через OpenGL и обработкой изображения в OpenCV. Проект позиционируется как учебный — подойдёт тем, кто хочет понять базовые приёмы компьютерного зрения и графики на практике.
Сканирование: показываете камере по одной грани по заранее заданным правилам. После скана жмёте Play, чтобы запустить анимацию, или листаете шаги кнопками Previous/Next — так удобно проверять, что распознание и сама сборка идут корректно.
Установка: клонируете репозиторий, выполняете
uv sync для зависимостей и запускаете uv run rubiksolver — автор использует современный менеджер uv, так что установка занимает минимум времени. Автор отмечает, что на Android встречаются решалки, но чаще всего там состояние кубика приходится вбивать руками, без автосканирования камерой — здесь как раз закрыта эта боль.
@zen_of_python
This media is not supported in your browser
VIEW IN TELEGRAM
3👍13❤1
Обвязка вокруг SQLAlchemy Core — sqla-fancy-core. Это не очередной ORM, а надстройка для тех, кто любит писать запросы сам, но хочет строгую типизацию, поддержку асинхронности и понятные транзакции без «магии» сессий.
Главная фишка — другой способ описывать таблицы вместо
Пример:
Проект задуман под продакшен: для тех, кто хочет конструктор запросов вместо ORM, но без потери читаемости и безопасности. По словам автора, в отличие от Peewee тут есть аннотации типов и официальная работа с async, Piccolo менее гибкий и сильно навязан по архитектуре, а Pypika не защищает от SQL‑инъекций по умолчанию. В итоге это просто способ сделать SQLAlchemy Core чуть более строгим и удобным, не меняя стек целиком.
Есть отдельное демо по использованию.
@zen_of_python
Главная фишка — другой способ описывать таблицы вместо
table.c.column, который нормально дружит с проверкой типов и делает код понятнее. Плюс поверх движка добавлены обёртки и декораторы: они берут на себя создание подключений и управление транзакциями.Пример:
import sqlalchemy as sa
from sqla_fancy_core import TableBuilder
tb = TableBuilder()
class Author:
id = tb.auto_id()
name = tb.string("name")
created_at = tb.created_at()
updated_at = tb.updated_at()
Table = tb("author")
Проект задуман под продакшен: для тех, кто хочет конструктор запросов вместо ORM, но без потери читаемости и безопасности. По словам автора, в отличие от Peewee тут есть аннотации типов и официальная работа с async, Piccolo менее гибкий и сильно навязан по архитектуре, а Pypika не защищает от SQL‑инъекций по умолчанию. В итоге это просто способ сделать SQLAlchemy Core чуть более строгим и удобным, не меняя стек целиком.
Есть отдельное демо по использованию.
@zen_of_python
1👎1👾1
T-строки в Python — новая техника форматирования, которая появилась в 3.14 и стала пятой в списке после
Главное отличие: t-строка сама по себе не делает готовую строку, а возвращает объект
Из-за этого t-строки полезны в первую очередь авторам библиотек: логированию, шаблонизаторам, SQL/HTML-обёрткам и любому коду, где хочется контролировать интерполяцию до склейки в строку. Для обычного прикладного кода ничего не меняется — продолжаете использовать f-строки, пока конкретная библиотека явно не попросит передать ей t-строку вместо готового текста.
Нырнуть поглубже можно в статье или на видео к посту.
@zen_of_python
%, str.format, string.Template и f-строк. Синтаксис очень похож на f-строки (те же {} и выражения), но результатом выражения t"..." будет уже не str, а объект шаблона.Главное отличие: t-строка сама по себе не делает готовую строку, а возвращает объект
Template, внутри которого по отдельности лежат куски текста и интерполяции со всеми их метаданными. Это даёт библиотекам возможность сначала пройтись по этим частям (экранировать, валидировать, форматировать), а уже потом собирать финальный вывод.Из-за этого t-строки полезны в первую очередь авторам библиотек: логированию, шаблонизаторам, SQL/HTML-обёрткам и любому коду, где хочется контролировать интерполяцию до склейки в строку. Для обычного прикладного кода ничего не меняется — продолжаете использовать f-строки, пока конкретная библиотека явно не попросит передать ей t-строку вместо готового текста.
Нырнуть поглубже можно в статье или на видео к посту.
@zen_of_python
Media is too big
VIEW IN TELEGRAM
1❤9
Свежий гайд от CodSpeed про то, как по‑нормальному бенчмаркать Python‑код, а не просто крутить timeit в REPL. Автор разбирает, чем отличается разовая прикидка скорости от «продакшен‑бенчмарков», которые гоняются в CI и ловят регрессии по перформансу между коммитами.
Фокус на подходе через тесты: пишете бенчмарки как pytest‑тесты, помечаете их маркером или используете benchmark‑фикстуру, а дальше CodSpeed через pytest-codspeed и GitHub Actions (или другой CI) автоматически собирает результаты, строит историю и подсвечивает, где вы случайно замедлили код. Плюс есть кейсы вроде параллельного прогонов, шардинга бенчей по нескольким CI‑джобам и интеграции в существующий пайплайн без переписывания уже имеющихся pytest-benchmark тестов.
Сам инструмент платный, но до 5 человек для коммерческих проектов доступен без проблем. Для опенсорса без ограничений.
@zen_of_python
Фокус на подходе через тесты: пишете бенчмарки как pytest‑тесты, помечаете их маркером или используете benchmark‑фикстуру, а дальше CodSpeed через pytest-codspeed и GitHub Actions (или другой CI) автоматически собирает результаты, строит историю и подсвечивает, где вы случайно замедлили код. Плюс есть кейсы вроде параллельного прогонов, шардинга бенчей по нескольким CI‑джобам и интеграции в существующий пайплайн без переписывания уже имеющихся pytest-benchmark тестов.
Сам инструмент платный, но до 5 человек для коммерческих проектов доступен без проблем. Для опенсорса без ограничений.
@zen_of_python
CodSpeed Docs
How to Benchmark Python Code? - CodSpeed Docs
Learn how to measure the performance of your Python code by writing and running benchmarks locally and continuously in CI to catch regressions.
🤔1
Сейчас обсуждается интересный pre‑PEP о внедрении Rust в CPython, с перспективой сделать Rust обязательной зависимостью при сборке в Python 3.17 после переходного периода в 3.15–3.16. В черновике расписан план: в 3.15 — предупреждение при сборке без Rust, в 3.16 — сборка без Rust только с явным флагом, в 3.17 — Rust может стать обязательным.
Зачем это нужно по версии авторов: безопасность памяти и потоков (важно на пути к free‑threaded Python), возможность писать быстрые части стандартной библиотеки на Rust. Есть референс‑имплементация: модуль _base64 на Rust, показывающий ускорение относительно C‑версии, и зафиксирован план FFI через новый crate cpython‑sys для доступа к C‑API CPython с минимальными unsafe‑участками.
@zen_of_python
Зачем это нужно по версии авторов: безопасность памяти и потоков (важно на пути к free‑threaded Python), возможность писать быстрые части стандартной библиотеки на Rust. Есть референс‑имплементация: модуль _base64 на Rust, показывающий ускорение относительно C‑версии, и зафиксирован план FFI через новый crate cpython‑sys для доступа к C‑API CPython с минимальными unsafe‑участками.
@zen_of_python
Tproger
В Python 3.17 предложили сделать Rust обязательным. CPython ждет крупнейшая реформа за 10 лет — Tproger
Python 3.17 может сделать Rust обязательным: CPython готовят к крупнейшей реформе за десятилетие — ради безопасности, скорости и будущего без GIL
🤯6❤3🤔2🙈2🆒1
Шаблон для ультра-строгих Python‑проектов — что‑то вроде
В этом шаблоне uv отвечает за управление проектом и зависимостями, ruff — за линтинг и форматирование, а basedpyright — за строгую статическую типизацию с максимальным количеством включённых проверок.
Забрать можно в репозитории, там же инструкции по использованию.
Для новых проектов просто копируете
И далее просто пользуетесь по необходимости:
Такой сетап хорошо заходит, если вы любите, когда инструменты сразу ломают билд за любые подозрительные места: неописанные типы, мёртвый код, неиспользуемые импорты, странные конструкции и т.п. Из минусов — порог входа выше: придётся либо писать типы везде, либо постоянно удовлетворять строгим линт‑правилам, но для долгоживущих библиотек и сервисов это может сильно окупиться.
@zen_of_python
--strict из TypeScript, но на стеке uv + ruff + basedpyright. Идея простая: вместо того, чтобы каждый раз настраивать линтеры, типизацию и менеджер окружений вручную, вы копируете готовый pyproject.toml и сразу получаете очень агрессивные правила по стилю и типам.В этом шаблоне uv отвечает за управление проектом и зависимостями, ruff — за линтинг и форматирование, а basedpyright — за строгую статическую типизацию с максимальным количеством включённых проверок.
Забрать можно в репозитории, там же инструкции по использованию.
Для новых проектов просто копируете
pyproject.toml, меняете секцию [project] под себя, создаёте src/your_package и tests/. Затем установка:uv venv
.venv\Scripts\activate # Windows
# или source .venv/bin/activate
uv pip install -e ".[dev]"
И далее просто пользуетесь по необходимости:
uv run ruff format .
uv run ruff check . --fix
uv run basedpyright
uv run pytest
Такой сетап хорошо заходит, если вы любите, когда инструменты сразу ломают билд за любые подозрительные места: неописанные типы, мёртвый код, неиспользуемые импорты, странные конструкции и т.п. Из минусов — порог входа выше: придётся либо писать типы везде, либо постоянно удовлетворять строгим линт‑правилам, но для долгоживущих библиотек и сервисов это может сильно окупиться.
@zen_of_python
1❤5
pymupdf4llm-C — извлекатель текста из PDF, написанный на C для скорости работы. Обходит PDF-страницы и сериализует блоки в структурированный JSON. Есть безопасные биндинги для Python и Rust без сырых указателей. Установка через pip:
Для каждой страницы создается JSON с массивом блоков:
Для таблиц добавляются
Как использовать
Можно писать в файлы:
Полезно, когда:
— требуется предсказуемая структура для векторных баз;
— нужно различать заголовки, списки, таблицы при чанкинге;
— скорость критична: C-реализация быстрее Python-аналогов;
— работаешь с документами, где важна иерархия и расположение элементов.
Перед использованием нужно собрать:
@zen_of_python
pip install pymupdf4llm-c или cargo: cargo add pymupdf4llm-c.Для каждой страницы создается JSON с массивом блоков:
[
{
"type": "paragraph|heading|table|list|figure",
"text": "content",
"bbox": [x0, y0, x1, y1],
"font_size": 11.0,
"font_weight": "normal",
"page_number": 0
}
]
Для таблиц добавляются
row_count, col_count, confidence. Координаты в PDF points, типы блоков для семантической обработки.Как использовать
from pymupdf4llm_c import to_json
# В память
results = to_json("report.pdf", collect=True)
for page in results:
for block in page:
if block['type'] == 'table':
process_table(block) # свой код для таблиц
Можно писать в файлы:
to_json(pdf_path, output_dir=Path("json")). Для Rust есть to_json_collect() и extract_page_json().Полезно, когда:
— требуется предсказуемая структура для векторных баз;
— нужно различать заголовки, списки, таблицы при чанкинге;
— скорость критична: C-реализация быстрее Python-аналогов;
— работаешь с документами, где важна иерархия и расположение элементов.
Перед использованием нужно собрать:
./build.sh. Проект свежий, но рабочий. Код в репо.@zen_of_python