У нас есть довольно большой проект на Python и вот мы решили мигрировать его со стандартного pip для управления зависимостями на современный и популярный uv.
Как было раньше: два файла -
requirements.txt с основным набором зависимостей и requirements-dev.txt - в нем добавлены некоторые дополнительные зависимости для локальной разработки и в тестах. Чтобы добавить их в pyproject.toml можно использовать uv add -r requirements.txtdev-файлик перезжает в uv в отдельную "группу" зависимостей. Зависимости такой группы можно поставить вместе с основными через флаг
--group name.Сам uv генерит
uv.lock файл, в котором зафиксирован слепок этих зависимостей, подзависимостей, транзитивных и так далее. Похоже на package-lock.json в Node.Основной воркфлоу теперь немного меняется:
-
uv sync создает виртуальное окружение (как раньше в .venv) и ставит в него все зависимости-
uv run <command> запускает команду в виртуальном окружении, например uv run python main.py- учитывая наличие
.venv после uv sync, можно сделать source .venv/bin/activate и работать как раньшеDockerfile тоже нужно переделать. Пример беру в официальном example-репозитории.
Сам бинарник uv беру из образа через
COPY, чтобы не конфликтовать по версии Python между pyproject.toml (там например зафиксирована 3.X.13) и официальным образом uv-python (они фиксируют только 3.X без патч-версии).Из интересных оптимизаций билда - использование mount-ов для RUN директив. Они позволяют использовать кэш на диске сборочного инстанса в случае инвалидации слоя - например поменялся слой с зависимостями, но мы все равно используем кэш, чтобы все не перекачивать.
В gitlab-ci настраиваю использование кэша:
cache:
key:
files:
- uv.lock
paths:
- .cache/uv
Если используете self-hosted докер-раннеры, то в настройках надо добавить:
[[runners]]
[runners.docker]
disable_cache = false
volumes = ["/var/path/to/cache:/cache"]
А вот что не получилось пока что сделать: указать кастомный индекс (nexus-proxy) для Python-зависимостей только на сборках/тестах. Чтобы при локальной установке качать зависимости с PyPi, а на сборке - с Nexus. При изменении index-url uv меняет uv.lock файл, чего я делать не хочу. Но, наверное, это логично.