Python в Rye-у

от автора

Rye — это пакетный менеджер для Python, написанный на Rust. Но Rye — это не только пакетный менеджер, но и удобный инструмент, который позволяет управлять проектами, зависимостями, виртуальными окружениями и версиями Python. Под капотом у Rye находится uv — более быстрый аналог pip, который, как и Rye, написан на Rust. Автором является небезызвестный Armin Ronacher.

Цель данной статьи провести краткое знакомство с новым инструментом управления зависимостями и проектами на Python.

Установка и настройка окружения

На macOS Rye можно установить через brew, но есть вероятность, что будет немного устаревшая версия. Другой способ установки:

curl -sSf https://rye.astral.sh/get | bash

Это универсальный способ, который будет работать и на macOS, и в Linux.
Я рекомендую устанавливать именно таким способом. И не только потому, что версия посвежее, но и потому, что в процессе такой установки будет возможность выбрать некоторые настройки. Например: использовать uv или pip для установки пакетов, заменять ли Python в системе или оставить как есть и т.д.

Стоит ещё отметить, что за собой Rye тащит сборку Python. А именно, используются вот эти вот готовые сборки: https://github.com/indygreg/python-build-standalone. Для людей с паранойей это может быть определяющим моментом в вопросе использовать Rye или нет. Подробнее про этот аспект можно почитать по ссылке: https://rye.astral.sh/guide/toolchains/cpython/

В завершении установки установщик спросит нужно ли добавить соурсинг прокладок. Правда, в моём случае установщик ошибся и записал соурсинг прокладок в .profile. Пришлось исправлять это самому

echo 'source "$HOME/.rye/env"' >> ~/.zshrc

Имейте в виду, что после установки и активации прокладок будет использовать тот Python, который закачает Rye, а не системный

% which python /Users/max/.rye/shims/python

Для удобства добавим комплишены

rye self completion -s zsh > ~/.zfunc/_rye

Надо убедиться, что .zfunc существует и добавлен в FPATH

Знакомство

Для начала надо инициализировать проект

% rye init rye-test success: Initialized project in /Users/max/work/rye-test   Run `rye sync` to get started

Посмотрим что получилось

% cd rye-test % ls -la total 32 drwxr-xr-x   9 max  staff   288 Sep  3 10:40 . drwxr-xr-x  69 max  staff  2208 Sep  3 10:37 .. drwxr-xr-x   9 max  staff   288 Sep  3 10:37 .git -rw-r--r--   1 max  staff    93 Sep  3 10:37 .gitignore -rw-r--r--   1 max  staff     7 Sep  3 10:37 .python-version drwxr-xr-x@  8 max  staff   256 Sep  3 10:40 .venv -rw-r--r--   1 max  staff    40 Sep  3 10:37 README.md -rw-r--r--   1 max  staff   469 Sep  3 10:37 pyproject.toml drwxr-xr-x   3 max  staff    96 Sep  3 10:37 src

Можно заметить, что Rye создал всё необходимое для работы с проектом.

А вот что в pyproject.toml

[project] name = "rye-test" version = "0.1.0" description = "Add your description here" authors = [     { name = "Maksim Piatyshev", email = "max@wectory.com" } ] dependencies = [] readme = "README.md" requires-python = ">= 3.8"  [build-system] requires = ["hatchling"] build-backend = "hatchling.build"  [tool.rye] managed = true dev-dependencies = []  [tool.hatch.metadata] allow-direct-references = true  [tool.hatch.build.targets.wheel] packages = ["src/rye_test"]

Сразу после создания можно запустить rye sync, который синхронизирует проект и создаст лок-файлы зависимостей.

Теперь всё готово для того, чтобы начать заводить себе новые зависимости

% rye add pyramid Added pyramid>=2.0.2 as regular dependency Reusing already existing virtualenv Generating production lockfile: /Users/max/work/rye-test/requirements.lock Generating dev lockfile: /Users/max/work/rye-test/requirements-dev.lock Installing dependencies Resolved 12 packages in 4ms    Built rye-test @ file:///Users/max/work/rye-test Prepared 12 packages in 1.34s Uninstalled 1 package in 0.62ms Installed 12 packages in 11ms  + hupper==1.12.1  + pastedeploy==3.1.0  + plaster==1.1.2  + plaster-pastedeploy==1.0.1  + pyramid==2.0.2  ~ rye-test==0.1.0 (from file:///Users/max/work/rye-test)  + setuptools==74.1.0  + translationstring==1.4  + venusian==3.1.0  + webob==1.8.8  + zope-deprecation==5.0  + zope-interface==7.0.3 Done!

Установка прошла, действительно, быстро и просто. После этого с проектом и его зависимостями можно работать как обычно — например, написать какой-то рабочий и полезный код без багов или что такое. Ну вы и сами всё знаете.

Интересности в Rye

Пока не было ничего необычного. Но у Rye есть кое-что…

Прокладки (shims)

После установки Rye предоставляет прокладки для python и python3. Эти прокладки работают так, что если мы не находимся в проекте под присмотром Rye, то будет запускаться системный Python, а если в проекте — Python из виртуального окружения проекта даже, если мы не делали его активацию. Это может быть полезно для тех, кто забывает активировать виртуальное окружение перед работай над проектом.
Дополнительно можно настроить Rye так, чтобы за пределами проекта прокладка подставляла не системный Python, а тот, что Rye приносит с собой во время установки

rye config --set-bool behavior.global-python=true

Причём, это никак не повлияет на что-то в системе, что зависит от системного Python.

https://rye.astral.sh/guide/shims/

Рабочие окружения (workspaces)

Рабочие окружения в Rye позволяют объединить несколько проектов и использовать одно общее виртуальное окружение для них. Это полезно для проектов в монорепозитории, где несколько пакетов или сервисов используют одни и те же зависимости — снижает накладные расходы на создание и управление зависимостями в нескольких проектах, обеспечивает согласованность версий и минимизирует конфликты зависимостей.

Чтобы включить эту возможность нужно в самом верхнем проекте прописать блок tool.rye.workspace

[tool.rye] virtual = true  [tool.rye.workspace] members = ["myname-*"]

Так все проекты, которые подпадают под шаблон myname-* станут частью данного workspace.

Необязательная опция virtual = true говорит, что топовый проект виртуальный в терминологии Rye — не устанавливаемый Python-пакет. Такой проект только содержит базовые настройки и зависимости и не будет установливаться как Python-пакет при деплое (не попадёт в requirements.lock). Вместо этого он служит только для хранения настроек рабочего окружения и управления зависимостями. Хотя, топовый проект worspace и не обязан быть виртуальным.

Рассмотрим на примере как сделать workspace.

Инициализация топового проекта с ключом виртуальности

rye init --virtual rye-test-workspace

Добавим признак рабочего окружения в pyproject.toml

...  [tool.rye.workspace] members = ["rye-test-*"]

Опция members позволяет ограничить каталоги по шаблону, которые будут считаться частью нашего рабочего окружения.

Синканём

% rye sync Initializing new virtualenv in /Users/max/work/rye-test-workspace/.venv Python version: cpython@3.12.5 Generating production lockfile: /Users/max/work/rye-test-workspace/requirements.lock Generating dev lockfile: /Users/max/work/rye-test-workspace/requirements-dev.lock Installing dependencies warning: Requirements file requirements-dev.lock does not contain any dependencies No requirements found (hint: use `--allow-empty-requirements` to clear the environment) Done!

Рабочее окружение готово к добавлению проектов

% rye init rye-test-1 % rye init rye-test-2

Посмотрим что внутри

% ls -la rye-test-* rye-test-1: total 32 drwxr-xr-x   7 max  staff  224 Sep  4 18:23 . drwxr-xr-x  12 max  staff  384 Sep  4 18:23 .. -rw-r--r--   1 max  staff   93 Sep  4 18:23 .gitignore -rw-r--r--   1 max  staff    7 Sep  4 18:23 .python-version -rw-r--r--   1 max  staff   42 Sep  4 18:23 README.md -rw-r--r--   1 max  staff  474 Sep  4 18:23 pyproject.toml drwxr-xr-x   3 max  staff   96 Sep  4 18:23 src  rye-test-2: total 32 drwxr-xr-x   7 max  staff  224 Sep  4 18:23 . drwxr-xr-x  12 max  staff  384 Sep  4 18:23 .. -rw-r--r--   1 max  staff   93 Sep  4 18:23 .gitignore -rw-r--r--   1 max  staff    7 Sep  4 18:23 .python-version -rw-r--r--   1 max  staff   42 Sep  4 18:23 README.md -rw-r--r--   1 max  staff  474 Sep  4 18:23 pyproject.toml drwxr-xr-x   3 max  staff   96 Sep  4 18:23 src

Теперь давайте сделаем синк в одном из проектов

% cd rye-test-1 % rye sync Reusing already existing virtualenv Generating production lockfile: /Users/max/work/rye-test-workspace/requirements.lock Generating dev lockfile: /Users/max/work/rye-test-workspace/requirements-dev.lock Installing dependencies Resolved 2 packages in 1ms    Built rye-test-1 @ file:///Users/max/work/rye-test-workspace/rye-test-1    Built rye-test-2 @ file:///Users/max/work/rye-test-workspace/rye-test-2 Prepared 2 packages in 1.91s Installed 2 packages in 1ms  + rye-test-1==0.1.0 (from file:///Users/max/work/rye-test-workspace/rye-test-1)  + rye-test-2==0.1.0 (from file:///Users/max/work/rye-test-workspace/rye-test-2) Done!

Видно, что Rye обнаружил уже существующее виртуальное окружение в проекте-родителе и не стал создавать его заного. Кроме этого Rye обнаружил второй проект и синканул и его тоже.

Попробуем добавить зависимость в текущий проект

% rye add lxml==5.2.0 Added lxml==5.2 as regular dependency Reusing already existing virtualenv Generating production lockfile: /Users/max/work/rye-test-workspace/requirements.lock Generating dev lockfile: /Users/max/work/rye-test-workspace/requirements-dev.lock Installing dependencies Resolved 3 packages in 2ms    Built rye-test-1 @ file:///Users/max/work/rye-test-workspace/rye-test-1 Prepared 1 package in 169ms Uninstalled 1 package in 0.57ms Installed 2 packages in 2ms  + lxml==5.2.0  ~ rye-test-1==0.1.0 (from file:///Users/max/work/rye-test-workspace/rye-test-1) Done!

Пакет lxml был добавлен не только в зависимости проекта rye-test-1, но в общее виртуальное окружение.
Теперь, если вдруг нам понадобился lxml в проекте rye-test-2 и мы решили его туда добавить, то будет использован уже добавленый в rye-test-1 пакет.
А вот, если в rye-test-2 мы решили установить пакет версии посвежее, то Rye нам сообщит о конфликте версий в зависимостях между проектами и не даст этого сделать (хотя список зависимостей rye-test-2 будет обновлён)

% cd ../rye-test-2 % rye add lxml==5.3.0 Added lxml==5.3.0 as regular dependency Reusing already existing virtualenv Generating production lockfile: /Users/max/work/rye-test-workspace/requirements.lock   × No solution found when resolving dependencies:   ╰─▶ Because you require lxml==5.2 and lxml==5.3.0, we can conclude that your requirements are unsatisfiable. error: could not write production lockfile for workspace  Caused by:     Failed to run uv compile /var/folders/dw/vk1bw2wd18zdpgs2m8lfzw4r0000gn/T/.tmpOcYdri/requirements.txt. uv exited with status: exit status: 1

К сожалению, Rye не говорит в каком проекте искать устаревшую зависимость. Но есть один способ это узнать

% cat ../requirements.lock # generated by rye # use `rye lock` or `rye sync` to update this lockfile # # last locked with the following flags: #   pre: false #   features: [] #   all-features: false #   with-sources: false #   generate-hashes: false #   universal: false  -e file:rye-test-1 -e file:rye-test-2 lxml==5.2.0     # via rye-test-1

Здесь сразу становится понятно, что устаревшая зависимость находится в rye-test-1.

Заключение по рабочим окружениям в Rye

Рабочие окружения в Rye — это мощный инструмент для разработки в монорепозиториях и мультипроектных средах. Они позволяют эффективно управлять зависимостями, используя общее виртуальное окружение для всех проектов внутри workspace. Это устраняет дублирование пакетов, сокращает время на настройку и синхронизацию окружений, а также уменьшает объем занимаемого пространства.

Кроме того, Rye помогает отслеживать и предотвращать конфликты версий: если какая-либо библиотека уже установлена в одной из частей workspace, и вы пытаетесь добавить её с несовместимой версией в другом проекте, Rye заблаговременно сообщит о проблеме. Это обеспечивает согласованность и предсказуемость зависимостей в масштабах всего рабочего окружения.

Таким образом, использование workspace особенно удобно в следующих сценариях:

  • Разработка в больших командах, где каждый проект имеет много общих зависимостей.

  • Работа с микросервисами или библиотеками внутри одной кодовой базы (монорепозитория), где важно поддерживать согласованные версии пакетов.

  • Проекты, где важно минимизировать время установки и обновления зависимостей и избежать возможных ошибок, связанных с несовместимостью версий.

Если у вас есть такие задачи, рабочие окружения в Rye могут значительно упростить процесс разработки и сделать управление зависимостями более прозрачным и удобным.

https://rye.astral.sh/guide/workspaces/

Заключение

Мы рассмотрели лишь базовые возможности Rye и одну из его ключевых особенностей — рабочие окружения. За рамками статьи остались такие важные аспекты, как упаковка проектов в Docker-образы, управление устанавливаемыми инструментами, автоматическая сборка и публикация пакетов, а также интеграция с CI/CD. Тем не менее, даже эти примеры показывают, насколько Rye отличается от других инструментов управления зависимостями в Python. Его легковесность, производительность и возможность управления рабочими окружениями делают Rye перспективным инструментом для тех, кто ищет более эффективный и гибкий способ организации Python-проектов. Использование Rye может стать отличным решением как для небольших команд, так и для крупных проектов, где важны согласованность зависимостей, скорость работы и удобство управления версиями Python.

Rye всё ещё находится в активной разработке, и его возможности продолжают расширяться. В будущем, он вполне может стать стандартным выбором для Python-разработчиков, особенно для тех, кто ценит производительность и простоту в настройке рабочих окружений. Если вы ещё не пробовали Rye, возможно, самое время протестировать его на небольшом проекте и оценить, насколько он подходит под ваши нужды.

Полезные ссылки:
https://rye.astral.sh/guide/
https://docs.astral.sh/uv/


ссылка на оригинал статьи https://habr.com/ru/articles/842134/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *