Пакетных менеджеров для питона как‑то слишком много. У этого, конечно, есть очевидная причина — скудность функционала pip, встроенного пакетного менеджера. Но всё равно внутренний перфекционист хочет простое решение из коробки. Установил питон — и сразу получаешь быстрый и удобный пакетный менеджер, и ещё желательно менеджер версий питона. Но вместо этого получаешь pip. Кто‑то, конечно, его реально пользует, но всё‑таки poetry, pdm, conda, pipenv или хотя бы pip‑tools гораздо удобнее.
Ну окей, казалось бы — всем хорош poetry. Я сам использую его в большинстве проектов. Но установка зависимостей начинает казаться медленной — особенно при пересборке docker‑контейнера. Плюс гемор с установкой самого poetry или со сменой версий питона — меняешь версию через, например, pyenv, а poetry при попытке пересоздания окружения выдает ошибку. Хотя предполагается что умеет работать с разными версиями питона. Решается, конечно, легко — через указание полного пути к интерпретатору, но всё равно костыли. Как и установка того же pyenv, и вообще работа с ним. А больше контролировать версии питона, вроде как, нечем.
И вот, в феврале появилось интересное решение от создателей Ruff. Пакетный менеджер UV, написанный на расте. Чисто консольный, конечно, причём синтаксис очень напоминает poetry. По функционалу это почти одно и то же, но с кучей плюшек и в несколько раз быстрее. В доке приведена вот такая диаграмма времени установки одинакового набора зависимостей:
Синтаксис действительно похож на poetry. Вот так, например, создаетс проект(сразу переходим в каталог):
uv init project_name
cd project_name
Там у нас вот такая вот структура:
project_name
├── .python-version
├── hello.py
├── pyproject.toml
└── README.md
Зависимости, как и у poetry, сохраняются в конфиге pyproject.toml
, версия питона - в .python-version
.
Создадим виртуальное окружение:
uv venv
Добавим SQLAlchemy в зависимости:
uv add sqlalchemy
Или можем добавить конкретную версию:
uv add sqlalchemy@2.0.32
Теперь удалим:
uv remove sqlalchemy
Теперь сахар - менеджмент версий питона. Поставим 3.11.9 и создадим окружение с таким интерпретатором.
uv python install 3.11.9
uv venv --python 3.11.9
Версия питона сохранится в .python-version
, и не надо при смене интерпретатора каждый раз указывать на это пакетному менеджеру, ведь UV и есть пакетный менеджер. Причём можно даже не устанавливать версию руками, а сразу создать окружение с нужной версией: если она не установлена, то UV сам её спуллит, то есть можно вообще об этом не думать - ну кайф же.
Как и в poetry, есть функционал по сборке и публикации пакетов на PyPI. Собрать контейнер и опубликовать пакет можно в две команды:
uv build
uv publish
Ещё можно использовать UV как супервизор, и запускать скрипты и приложения при помощи uv run
И вишенка на торте - docker образ.
FROM ghcr.io/astral-sh/uv:python3.12
WORKDIR /app
RUN uv venv
CMD ["run", "app"
Ненадо пуллить образ питона и там устанавливать UV через pip, можно сразу спуллить образ UV и кайфовать. Плюс там ещё много всяких фишек, но об этом в доке (которая, кстати, очень понятная) — те, кому эти фишки нужны в доку полезть не побоятся.
В целом, реально удобный тул и хорошая альтернатива poetry. Ни в одной IDE пока нет поддержки UV, но это вопрос времени. Круто, что столько фишек, хочется, чтобы проект развивался. Делитесь этим постом и пишите, чем пользуетесь вы.
Комментарии (8)
Morthan
26.12.2024 12:48Можно подробнее про
uv run
? Это аналогpipenv run
? То есть, можно в файле конфигурации написать скрипты и вызывать их этой командой?dmkjfs Автор
26.12.2024 12:48ага, или poetry run. Можно запускать скрипты на питоне или консольные приложения из пакетов(тесты, линтеры и ещё кучу всего). Насчёт файлов конфигурации в которых задаются скрипты не уверен, надо доку почитать
Morthan
26.12.2024 12:48Сайт с докой не открывается, а раскочегаривать VPN мне лень. Давайте на примере. У меня в
Pipfile
есть такая секция:[scripts] env = "invoke env" update = "invoke update" floors = "invoke floors" index = "invoke index" serve = "invoke serve" fast-release = "invoke fast-release" version-up = "invoke version-up" uplift = "invoke uplift" deploy = "invoke deploy"
При запуске, скажем,
pipenv run fast-release
активируется окружение и запускается командаinvoke
с параметромfast-release
(именем задачи).Какую секцию мне нужно прописать в
pyproject.toml
, чтобы я мог написатьuv run fast-release
и произошло то же самое?
Andrey_Solomatin
В некоторых случаях можно достигнуть хорошего ускорения используя --resolution lowest (https://docs.astral.sh/uv/concepts/resolution/#resolution-strategy). Если у все в логах много скачиваний разных версий одного и того-же пакета в поиске подходящей версии.
dmkjfs Автор
да там вообще много крутых вещей - и по функционалу и по скорости, я много чего выпустил. И дока понятная кстати