ちょっと話題の記事

【Pythonのパッケージ管理に悩む方へ】パッケージ管理ツールRyeを使ってみた

ライ麦畑で「Pythonパッケージを」つかまえたい
2023.10.08

こんちには。

データアナリティクス事業本部 インテグレーション部 機械学習チームの中村です。

今回はRyeを使ったPythonの実行環境構築についてご紹介します。

Ryeについて

RyeはRustで実装された、Python環境をワンストップで管理できるツールとなっています

今まではpyenv + poetryやpyenv + pipenvなどpyenvとの組み合わせで構築が必要だったものが、RyeだけでPythonインタープリタ含めて管理することが可能です。

RyeはRustのrustupとcargoにインスパイアされた、Pythonの新しいパッケージング体験を構築する実験的な試みとなっており、作者により「Production Readyではない」と紹介されていますが、検証用等個人で使用するには使い勝手はかなり良かったのでご紹介致します。

公式ページは以下となります。

セットアップ

インストール

以下に沿って実施します。

ページ上にあるOSに沿ったバイナリをダウンロードします。

私はWindowsを使用していますのでrye-x86_64-windows.exeをインストールしました。

過去のバージョンを含むバイナリは、GitHubの以下からもダウンロードできます。

ダウンロードしたバイナリの実行すると以下のようなターミナルが立ち上がりますので、必要に応じてインタラクション操作を実行します。

Welcome to Rye!

Rye has detected that it's not installed on this computer yet and
automatically started the installer for you.  For more information
read https://rye-up.com/guide/installation/

This installer will install rye to C:\Users\{ユーザ名}\.rye
This path can be changed by exporting the RYE_HOME environment variable.

Details:
  Rye Version: 0.14.0
  Platform: windows (x86_64)

Continue? yes
Installed binary to C:\Users\{ユーザ名}\.rye\shims\rye.exe
Bootstrapping rye internals
Downloading cpython@3.11.5
Checking checksum
success: Downloaded cpython@3.11.5
Upgrading pip
Installing internal dependencies

環境変数の追加

ターミナルが閉じられインストールが終わりましたら、以下を環境変数PATHに追加します。

  • %USERPROFILE%\.rye\shims

バージョンの確認

正常にインストールできているか確認するために、以下でバージョンをします。

rye --version

# rye 0.14.0
# commit: 0.14.0 (39428bb9e 2023-10-01)
# platform: windows (x86_64)
# self-python: cpython@3.11
# symlink support: true

バージョン番号が表示されていることを確認して次に進みます。

プロジェクトの作成

Ryeでの管理を始めるには、initを使います。

rye init my-project

または、既存のフォルダ内でRyeでの管理を始める場合は、プロジェクト名を指定せずにinitすることも可能です。

rye init

どちらの方法でも、実行後は以下のようなファイルが作成されます。

my-project
│  .gitignore
│  .python-version
│  pyproject.toml
│  README.md
│
└─src
    └─my_project
            __init__.py

パッケージを作らない場合で仮想環境だけを使用したいケースでは、src配下は不要な場合は削除してしまっても良いかもしれません。

以降はプロジェクトのフォルダ内で作業します。

cd my-project

Pythonバージョンの指定

pinによるPythonバージョンの指定

現在の状態でも、Pythonバージョンは.python-versionというファイルに以下のように記載されています。

cpython-x86_64-windows@3.12.0

このPythonバージョンを、pinコマンドでバージョンを変更することが可能です。

rye pin 3.11

# pinned 3.11.6 in {プロジェクトの絶対パス}\.python-version

実行後.python-versionファイルは以下のように変更されます。

3.11.6

初回のsyncコマンド

この状態でsyncコマンドを実行することで設定を反映することができます。

rye sync

# Downloading cpython@3.11.6
# Checking checksum
# success: Downloaded cpython@3.11.6
# ...
# Successfully built my-project
# Installing collected packages: my-project
# Successfully installed my-project-0.1.0
# Done!

これが初回のsyncコマンドとなり、以後パッケージを変更等する都度にsyncコマンドが必要となります。

これがRyeの特徴の一つとなります。

初回のsyncにより、以下のように.venvが作成され、requirements-dev.lockおよびrequirements.lockが作成されます。

my-project
│  .gitignore
│  .python-version
│  pyproject.toml
│  README.md
│  requirements-dev.lock
│  requirements.lock
└─.venv/

Python本体は.venvに格納され、以降で入れていくパッケージも基本的にこの配下に格納されていきます。

なお、Pythonのダウンロード自体は毎回されるわけではなく、既にダウンロードしたことがあるバージョンの場合はあるフォルダから取得されます。

実際ダウンロードされるPythonは、仮想環境内ではなく、以下のディレクトリに格納されているようです。

  • %USERPROFILE%\.rye\py

ここに格納されているPythonをツールチェインと呼びます。(詳細は後述のツールチェインの章を参照)

依存パッケージの管理(基本)

依存パッケージの追加

基本的にはaddで追加することができます。

rye add boto3

# Added boto3>=1.28.62 as regular dependency

複数ある場合は、add以降に複数記述することも可能です。

これは「依存関係の追加(add)」という扱いとなり、実際にパッケージはまだインストールされず、pyproject.tomldependenciesが追加されている形となります。

[project]

# ...中略...

dependencies = [
    "boto3>=1.28.62",
]

依存関係の反映

ここでパッケージをインストールするにはsyncを実行します。

rye sync

# Installing dependencies
# Found existing installation: my-project 0.1.0
# ...中略...
# Successfully built my-project
# Installing collected packages: urllib3, six, s3transfer, python-dateutil, my-project, jmespath, botocore, boto3
# Successfully installed boto3-1.28.62 botocore-1.31.62 jmespath-1.0.1 my-project-0.1.0 python-dateutil-2.8.2 s3transfer-0.7.0 six-1.16.0 urllib3-2.0.6
# Done!

これでパッケージがインストールされ、requirements.lockrequirements-dev.lockが更新されます。

requirements.lockは以下のようになります。

-e file:.
boto3==1.28.62
botocore==1.31.62
jmespath==1.0.1
python-dateutil==2.8.2
s3transfer==0.7.0
six==1.16.0
urllib3==2.0.6

requirements-dev.lockも内容は上記と同じです。

依存関係の削除

依存関係の削除はremoveで行います。

rye remove boto3

反映には、syncの実行が必要です。

addとremoveの同時反映

syncを最後に実行するという仕様となっているため、ある依存関係をremoveして別のものをaddする、という行為も一括でsyncで反映できる点は便利と感じました。

ある依存パッケージの最新化

あるパッケージを最新化するのは、通常のパッケージを追加するのと同じ手順で可能です。

具体的には以下のようにします。

rye add boto3

反映には、syncの実行が必要です。

この方法で最新化されるのは、バージョン未指定の場合、pyproject.tomlで最新版以上という形となるためです。

依存パッケージの管理(開発用)

開発用の依存パッケージの追加

開発用途のみでの使用が想定されるパッケージ、例えばblackpytestなどを追加するには、addコマンドで--devオプションを付けます。

rye add --dev pytest

# Added pytest>=7.4.2 as dev dependency

この場合pyprojet.tomlは、dev-dependenciesに依存関係が追加されます。

[tool.rye]
managed = true
dev-dependencies = [
    "boto3>=1.28.62",
    "pytest>=7.4.2",
]

反映するにはsyncを実行します。

この場合、sync後はlockファイルもrequirements-dev.lockのみが更新されます。(内容は省略)

開発用の依存関係の削除

依存関係の削除はremoveで行います。

rye remove boto3

開発用の依存関係の削除には、--devを付ける必要があります。

rye remove --dev pytest

反映するにはsyncを実行します。

依存関係の再構築

同じ状態を再構築

同じ状態を再構築したい場合は、単純にlockファイルのある場所でsyncをすればOKです。

rye sync

この処理は、requirements-dev.lockの開発側をデフォルトで見に行きます。

開発側ではない方を使って再構築する場合は--no-devオプションが必要となります。

rye sync --no-dev

一旦クリーンして再構築

何かしらの不具合が発生した場合に、バージョンを再現する必要が無いケースでは、特に固定されたバージョンにこだわらずにsyncしたいケースも考えられます。

その倍は.venvや2つのlockファイルを削除後にsyncをすれば、pyproject.tomlを元に再構築できます。

依存関係をpipに渡して再構築

自身ではRyeで管理しているが、渡したい相手がそうでない場合が考えられます(通常、pipが主流と考えられます)。

これはRyeの機能を使って実現は難しいのですが、requirements.lockを少し編集することで可能です。

具体的には-e file:.となっている箇所のみを取り除いてrequirements.txtとして保存します。

# -e file:.
boto3==1.28.62
botocore==1.31.62
jmespath==1.0.1
python-dateutil==2.8.2
s3transfer==0.7.0
six==1.16.0
urllib3==2.0.6

このrequirements.txtを使って、pip環境では以下のようにインストールをすれば再構築できます。

pip install -r requirements.txt

ただしこれは公式で紹介されているというわけではないため、その点はご注意ください。

その他の依存関係の追加方法

依存パッケージのバージョン指定

以下のような記述でバージョン指定も可能となっています。

rye add "boto3==1.28.62"

(なおバージョン未指定の場合は、現在の最新版以上という風に解釈されていました)

extraパッケージの依存関係を追加

extra/featureパッケージの依存関係を追加するには、PEP 508に準拠した四角括弧表記を使用するか、以下のように--featuresオプションを使用することもできます。

rye add Flask --features=dotenv

Gitまたはローカルの依存関係を追加

RyeでもGitのレポジトリを指定して依存関係を追加することができます。

rye add Flask --git=https://github.com/pallets/flask

gitの依存関係については、--tag、--rev、--branchなど、あらゆる種類の追加パラメータがサポートされています。

またローカルのパッケージを追加することも可能です。

rye add my-utility --path ./my-utility

仮想環境で作業する

仮想環境に入る

仮想環境に入る場合は、.venv/Scriptsにあるactivateを実行するのが、公式で紹介されている手法です。

.\.venv\Scripts\activate

仮想環境に入ることに成功した場合、ターミナルの左端に以下のような表示が現れます。

(my-project)

また現在仮想環境に入っているかどうかは、以下で確かめることができます。

python -c "import sys; print(sys.prefix)"

# {プロジェクトの絶対パス}\.venv

この結果が作成した.venvの絶対パスとなっていれば、仮想環境に入った状態となります。

仮想環境から抜ける

仮想環境から抜けたい場合は、deactivateを実行します。

deactivate

仮想環境に入る(別解)

またactivateではなくshellコマンドで仮想環境に入る方法もあるようです。

rye shell
python -c "import sys; print(sys.prefix)"

# {プロジェクトの絶対パス}\.venv

この場合、仮想環境から抜けるにはexitを実行します。

exit

仮想環境上で実行する

仮想環境に入ることなく、仮想環境で何かを実行したい場合は以下のようにrunを使用すれば可能です。

rye run python --version

# Python 3.11.6

RyeとグローバルPython

グローバルPythonもRyeの方を使いたい

以下の設定をすることで、Ryeで管理するPythonをシステムのデフォルトで使用することができます。

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

ただし、PATHがどこに解決されるかにも依存しますので、以下のような点を必要であれば見直す必要があります。

上記が可能であれば実施することで、RyeのPythonに解決するようにすれば、以下のようにRye側のPythonが使用できます。

python -c "import sys; print(sys.prefix)"

# C:\Users\{ユーザ名}\.rye\py\cpython@3.11.6\install

通常、現在使用可能な最新版がこの場合使用される形となります。

グローバルPythonのバージョンを指定

また別のPythonのバージョンを指定したい場合、+3.9などのオプションを付けて実行することで可能です。

python +3.9 -c "import sys; print(sys.prefix)"

# error: Requested Python version (cpython@3.9.18) is not installed. Install with `rye fetch cpython@3.9.18`

このようにツールチェインにない場合は、fetchが必要なのでfetchで取得します。

rye fetch cpython@3.9.18

# Downloading cpython@3.9.18
# Checking checksum
# success: Downloaded cpython@3.9.18
python +3.9 -c "import sys; print(sys.prefix)"

# C:\Users\{ユーザ名}\.rye\py\cpython@3.9.18\install

ツールチェイン

ここまでで出てきたツールチェインについてここで説明します。公式では以下に記載があります。

Ryeのユニークな点は、システムPythonのインストールを使用しないことであり、Pythonのインストールを自らダウンロードして管理します。

これをRyeではツールチェインと呼んでいます。

現在、Ryeでサポートされているツールチェーンは3種類あり、以下の3つがあります。

  • ポータブルCPython : Ryeは、必要なCPythonのポータブルビルドをダウンロードします。これらはindygreg/python-build-standaloneから取得します。
  • 公式PyPyビルド : PyPyは公式リリースビルドからサポートされています。
  • カスタムローカルツールチェーン:ローカルにインストールされたPythonインタプリタをRyeに登録できます。 登録後は、Ryeが管理する全てのプロジェクトで使用できます。

現在、使用可能なfetch済みのツールチェインは以下で確認できます。

rye toolchain list

# cpython@3.11.6 (C:\Users\{ユーザ名}\.rye\py\cpython@3.11.6\install\python.exe)
# cpython@3.9.18 (C:\Users\{ユーザ名}\.rye\py\cpython@3.9.18\install\python.exe)

またfetchして取得可能なツールチェイン一覧は以下で確認ができます。

rye toolchain list --include-downloadable

# ...

ローカルのPythonをRyeに登録するには以下のようにします。

rye toolchain register /path/to/python

またツールチェーンを削除するには以下のようにします。

rye toolchain remove cpython@3.9.18

グローバルなツールの管理

Ryeはグローバルツールのインストールをサポートしています。

例えばblackruffなどの静的解析ツールをグローバルにインストールするなどが可能です。

インストール

rye tools installでインストールができますが、エイリアスとしてrye installが使用可能です。

例えばblackという静的解析ツールをグローバルにインストールします。

rye install black

依存関係が宣言されておらず適切にインストールできない場合は、--extra-requirementで依存関係を指定することができます。

rye install gradio --extra-requirement setuptools

ツール一覧

以下でグローバルなツールの一覧を確認できます。

rye tools list

# black

アンインストール

rye tools uninstallでアンインストールができますが、エイリアスとしてrye uninstallが使用可能です。

rye uninstall black

Rye自身に対する操作

Ryeのアップデート

rye自身のアップデートは以下で実行できます。

rye self update

Ryeの削除

rye自身の削除は以下で実行できます。

rye self uninstall

ワークアラウンド

Rye特有ではない可能性がありますが、例えばpkg_resourceが無いというエラーが出る場合があります。

ModuleNotFoundError: No module named 'pkg_resources'

その場合は、setuptoolsをインストールしてみてください。

rye add setuptools
rye sync

まとめ

いかがでしたでしょうか。少し長くなりましたがPythonのパッケージ管理ツールであるRyeを今回ご紹介いたしました。

こちらがPythonのパッケージ管理に悩む皆様のご参考になれば幸いです。

参考リンク