В мире Python управление зависимостями является краеугольным камнем разработки. Долгое время менеджер pip был де-факто стандартом, но со временем сообщество начало искать
более быстрые и надежные решения. Недавно на горизонте появился новый игрок – uv, разработанный командой Astral, который обещает революционную скорость в установке и разрешении пакетов.
uv представляет менеджер пакетов Python на основе Rust, созданный для быстрой и надежной работы.
Его основная цель – обеспечить максимально быструю установку, разрешение зависимостей и создание виртуальных окружений, значительно превосходя по скорости существующие альтернативы.
uv заменяет как пакетный менджер pip, так и ряд других инструментов как
pip-tools, virtualenv и ряд других.
По некоторым оценкам создание виртуальных окружений с помощью uv примерно в 80 раз быстрее, чем с помощью команды python -m venv.
А установка пакетов в 4–12 раз быстрее без кэширования и примерно в 100 раз с кэшированием. Скорость uv обусловлена несколькими ключевыми факторами:
Rust под капотом:: Использование Rust позволяет uv достигать производительности, недоступной для инструментов, написанных на Python. Rust компилируется в машинный код, что обеспечивает минимальные накладные расходы и эффективное использование системных ресурсов.
Параллельная обработка:: uv активно использует параллелизм для загрузки и установки пакетов, что значительно сокращает время ожидания.
Оптимизированное разрешение зависимостей:: Алгоритмы разрешения зависимостей в uv были разработаны с учетом производительности, что позволяет ему быстро находить совместимые версии пакетов даже в сложных графах зависимостей.
Использование кэша:: uv эффективно кэширует загруженные пакеты, минимизируя повторные загрузки.
uv предлагает набор функций, необходимых для эффективного управления пакетами:
Создание виртуальных окружений (uv venv): Позволяет быстро создавать изолированные виртуальные окружения для ваших проектов, подобно python -m venv
Установка пакетов (uv install): Устанавливает пакеты из PyPI или локальных источников с молниеносной скоростью. Поддерживает установку из requirements.txt.
Обновление пакетов (uv update): Обновляет установленные пакеты до последних совместимых версий.
Удаление пакетов (uv uninstall): Удаляет пакеты из виртуального окружения.
Синхронизация зависимостей (uv sync): Читает файл requirements.in (или pyproject.toml в будущем) и синхронизирует виртуальное окружение, устанавливая или удаляя пакеты для соответствия определенным зависимостям. Эта команда особенно полезна для обеспечения воспроизводимости сборок.
Компиляция зависимостей (uv compile): Генерирует файл requirements.txt (или аналог requirements.lock), который содержит фиксированные версии всех зависимостей, обеспечивая детерминированные сборки. Это аналог pip-compile из pip-tools.
Аудит зависимостей (uv pip check): Проверяет целостность установленных пакетов и выявляет конфликты.
Установка uv очень проста. Его можно установить с помощью установщика, загрузив установщик с официального сайта, либо можно установить с помощью различных пакетных менеджеров. Рассмотрим различные способы.
На Linux/MacOS для загрузки и установки с помощью установщика можно использовать утилиту curl:
curl -LsSf https://astral.sh/uv/install.sh | sh
либо утилиту wget (если curl не установлена):
wget -qO- https://astral.sh/uv/install.sh | sh
На Windows применяется утилита powershell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Также в качестве альтернативы для установки можно использовать ряд пакетных менеджеров. Например, установка с помощью пакетного менеджера pip:
pip install uv
Установка с помощью пакетного менеджера pipx:
pipx install uv
Либо с помощью пакетного менеджера Homebrew:
brew install uv
Основные команды uv:
uv init <project-name>: Создает и инициализирует проект Python с базовой структурой
uv venv: Создает в текущем проекте новую виртуальную среду
uv add <package-name>: Добавляет к зависимостям проекта пакет с именем package-name
uv pip install -r requirements.txt: Устанавливает все зависимости, указанные в файле requirements.txt
uv remove <package-name>: Удаляет пакет из зависимостей проекта
uv run script.py: Запускает скрипт Python или команду внутри проекта
uv sync: Устанавливает все зависимости из файла uv.lock
Рассмотрим базовые примеры использования.
uv init hello
В результате будет создана новая папка "hello", которая будет иметь следующую структуру:
git: папка для работы с Git
main.py: автосгенерированный файл приложения с некоторым стандартным кодом по умолчанию
pyproject.toml: файл конфигурации проекта
README.md: описание проекта
.python-version содержит номер применяемой версии Python
Эта та базовая структура, от которой мы можем дальше отталкиваться.
Для работы с пакетами нам потребуется виртуальная среда. Хотя uv автоматически инициализирует виртуальную среду в проекте при первом запуске скриптов или при установке пакетов, но также можно создать виртуальную среду явным образом с помощью команды uv venv, которой передается имя среды. Если имя среды не указано, то по умолчанию используется имя ".venv".
Итак, перейдем в консоли к папке проекта и введем команду uv venv:
eugene@Eugene:/workspace/python/hello$ uv venv Using CPython 3.12.3 interpreter at: /usr/bin/python3.12 Creating virtual environment at: .venv Activate with: source .venv/bin/activate eugene@Eugene:/workspace/python/hello$
После выполнения в проекте будет создан каталог виртуальной среды .venv и файл
Для активации среды применяется одна из следующих команд:
Для MacOS/Linux: source .venv/bin/activate
Для Windows: .venv\Scripts\activate
Для установки пакетов применяется команда uv add <имя_пакета>. Рассмотрим на примере установки популярного пакета для отрисовки графиков matplotlib. Для его установки выполним команду uv add matplotlib:
eugene@Eugene:/workspace/python/hello$ uv add matplotlib
Resolved 12 packages in 348ms
░░░░░░░░░░░░░░░░░░░░ [0/11] Installing wheels... warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
If the cache and target directories are on different filesystems, hardlinking may not be supported.
If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 11 packages in 285ms
+ contourpy==1.3.3
+ cycler==0.12.1
+ fonttools==4.59.0
+ kiwisolver==1.4.8
+ matplotlib==3.10.5
+ numpy==2.3.2
+ packaging==25.0
+ pillow==11.3.0
+ pyparsing==3.2.3
+ python-dateutil==2.9.0.post0
+ six==1.17.0
eugene@Eugene:/workspace/python/hello$
При добавлении пакетов команда uv обновляет файл pyproject.toml. Так, в нем появляется запись о добавленной зависимости:
[project]
name = "hello"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"matplotlib>=3.10.5",
]
Кроме того, uv определяет полное дерево зависимостей, создавая файл uv.lock.
Стоит отметить, что если пакет отсутствует в среде, но используется в запускаемом скрипте, uv установит его при запуске скрипта, если зависимость указана в файле toml.
Для запуска скриптов Python применяется команда uv run, которой передается имя файла скрипта. Например, при создании проекта uv создает файл main.py с некоторым содержимым по умолчанию. Этот скрипт выглядит примерно так:
def main():
print("Hello from hello!")
if __name__ == "__main__":
main()
Здесь определена функция main, которая выводит некоторое сообщение на консоль. Запустим этот скрипт:
eugene@Eugene:/workspace/python/hello$ uv run main.py Hello from hello! eugene@Eugene:/workspace/python/hello$
Итак, у нас отработал скрипт, как и ожидалось. Но выше мы добавили в проект библиотеку matplotlib. Используем ее и для этого изменим файл main.py следующим образом:
import matplotlib.pyplot as plt # импортируем функциональность модуля pyplot из пакета matplotlib
def main():
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
rates = [13.58, 15.33, 14.26, 13.92, 12.74, 12.2, 13.44, 15.63, 15.74, 17.08, 17.18, 16.66]
# метка по оси X
plt.xlabel("month")
# метка по оси Y
plt.ylabel("rate")
plt.plot(months, rates)
plt.show()
if __name__ == "__main__":
main()
Так как этот код приведен больше для демонстрации, то рассмотрим вкратце, что он делает. Здесь список months хранит сокращенные названия месяцев, а rates - показатели популярности.
С помощью функции xlabel() устанавливаем метку для оси Х, а с помощью функции ylabel() - для оси Y. В функцию plot() передаются
два списка - для отображения по оси X (здесь список months) и по оси Y (здесь список rates). Функция plot() принимает набор значений, которые надо
вывести на графике. С помощью функции show() отображаем график в окне просмотра по умолчанию.
После изменения файла снова запустип скрипт на выполнение:
uv run main.py
В итоге нам отобразится следующее окно:
Таким образом, мы можем работать с пакетным менеджером uv, управлять пакетами Python и виртуальными средами, запускать скрипты. И это только небольшая часть возможностей, которые предоставляет uv.