社内プロキシ配下でryeを使う（Pythonパッケージ管理ツール）

# 2024年4月26日追記

この記事ではRye 0.15.2を利用していますが、記事執筆後にリリースされたRye 0.18.0のリリースノートを確認したところ、以下のような記載がありました。

>Disable revocation checks on windows to support corporate MITM proxies. #537

要は、Windowsにおける証明書の失効チェックが行われなくなったとのことです。従って、0.18.0以降にアップデートすれば、本記事での`Ryeのインストール`節や`rye sync: 指定したバージョンのPythonバイナリとライブラリをインストール`節で紹介しているエラーは発生せず、環境変数さえ設定すれば社内プロキシ配下でも自由に利用可能という現状になっています。（ありがたい・・・！）

繰り返しになりますが、これ以降の内容は、Rye 0.15.2を利用した際の内容であり、最新バージョンはこの記事でのRyeの挙動とは異なるということ、ご了承ください。



# はじめに

こんにちは！
私は普段Pythonを使ってコーディングをすることが多いのですが、Pythonのパッケージ管理は様々なツールが群雄割拠の状況であり、何を使うべきか悩まされることが多いです。

本記事では、数あるパッケージ管理ツールの中で、個人的に使い勝手が良いと感じた**Rye**を紹介します。また、**社内プロキシ環境で使う上で躓いた点とどう対処したか**についても記していきたいと思います。

# Ryeとは

**Rye**は、Armin Ronacher氏がRustにて開発した**Pythonのパッケージ管理ツール**です。

各種リンクは以下の通りです。
+ [ドキュメント](https://rye-up.com/)
+ [GitHub](https://github.com/mitsuhiko/rye)


Ryeができることとして、例えば以下があります。

+ Pythonのインストール、及びバージョン管理
+ ライブラリのバージョン、依存関係の管理
+ 仮想環境（venv）の作成

これまで、私はpoetryをよく使っていましたが、Pythonのインストールやバージョン管理は個別に実施するか、pyenvといった別のツールを利用する必要がありました。一方、**Ryeを使えばPythonの管理も含めて、ワンストップで行えます**。また、Rust製ということで動作も早く、個人的に使い勝手がよいなあと感じております。 

:::note warn
Githubやドキュメントでも述べられている通り、Ryeはまだ`Experimental`な段階とのことなので、個人開発や検証のみに使うことをお勧めします。
:::

# Ryeを社内プロキシ環境で使う

それでは、Ryeを社内プロキシ環境で使ってみたいと思います。
本記事では以下を実施します。

+ Ryeのインストール
+ Ryeプロジェクトの作成
+ ライブラリの追加
+ Pythonバージョンの変更

また、動作環境は以下の通りです。

+ OS : Windows10
+ rye : 0.15.2

:::note 
本記事の趣旨は「社内プロキシ環境でRyeを使う」であるため、基本的な使い方しか紹介しません。もし、よりDeepな機能を知りたい方は公式のドキュメントや、以下をはじめとした他の方の記事を参照していただければと思います。

+ [pythonパッケージ管理ツールryeを使う](https://nsakki55.hatenablog.com/entry/2023/05/29/013658)
+ [【Pythonのパッケージ管理に悩む方へ】パッケージ管理ツールRyeを使ってみた](https://dev.classmethod.jp/articles/get-start-rye-python/)
+ [久しぶりのPython環境をRyeで整える](https://zenn.dev/watany/articles/f69db9e33d4427)
+ [Pythonのパッケージ管理は「rye」が使いやすい！](https://qiita.com/ku_a_i/items/2cbcc576f44ff759b588)
:::

## Ryeのインストール

### とりあえずドキュメントに従ってインストール

以下のドキュメントに従ってインストールを行います。
https://rye-up.com/guide/installation/

上記ページから、お使いのPCに合った実行ファイルをダウンロードし実行すると、**ryeのバイナリ（`rye.exe`）と、内部用のPythonバイナリ**がダウンロードされます。

:::note info
Ryeは裏で`pip-tools`を利用しているとのことで、ここでPythonをインストールする理由は、主にそれら内部の用途のためという認識です。
:::

それでは以下を実行し、**社内プロキシ環境で実際にインストール**してみます。

```
set RYE_HOME=C:\hogehoge\rye
rye-x86_64-windows.exe
```
以下、インストールの詳細です。
+ 実行環境はWindows（64ビット）であったため、それに合わせて`rye-x86_64-windows.exe`でインストールを実行しています。
+ 環境変数`RYE_HOME`に`C:\hogehoge\rye`を指定し、ダウンロード先をデフォルト（`%USERPROFILE%\.rye`）から変更しています。
+ Rye `0.15.2`において、内部用のPythonのデフォルトバージョンは`cpython@3.11.6`でした。

実行結果は以下の通りです。

```title:実行結果
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:\hogehoge\rye
This path can be changed by exporting the RYE_HOME environment variable.

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

Continue? yes
Installed binary to C:\hogehoge\rye
Bootstrapping rye internals
Downloading cpython@3.11.6
error: failed to fetch internal cpython toolchain cpython@3.11

Caused by:
    0: download of https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6%2B20231002-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst failed
    1: [35] SSL connect error (schannel: next InitializeSecurityContext failed: Unknown error (0x80092012))
Press any key to continue
```

早速、`SSL connect error`が発生しました。ログを読み取ると、Ryeのインストールは成功したものの、**Pythonのインストール時、`github.com` へアクセスした際にエラーが発生した**という状況の様です。（実際に、`rye.exe`は所定のディレクトリにインストールされていましたが、Pythonはありませんでした。）

実は、**弊社内プロキシが`github.com`へのアクセスの際に証明書を指定する必要があり**、これが原因であると考えられます。

じゃあ、証明書を指定すればよいという話になるのですが、ドキュメントを見てもその方法は見つかりませんでした。以下の進行中のイシューでも同様の事象が発生しており、現状はできなさそうです。（もし、ご存じの方がいれば、教えてくださいm(__)m）

https://github.com/mitsuhiko/rye/issues/457

今回は回避策として、**手動でPythonバイナリをダウンロード**して、それをRyeに読み込ませたいと思います。これは、Ryeのインストールの前に**環境変数`RYE_TOOLCHAIN`** を設定することで実現できます。

例えば、[ドキュメント](https://rye-up.com/guide/installation/#installing-rye)では、以下のように指定しています。
```
set RYE_TOOLCHAIN=%USERPROFILE%\AppData\Local\Programs\Python\Python310\python.exe
rye-x86_64-windows.exe
```
この例では、`%USERPROFILE%\AppData\Local\Programs\Python`配下にインストール済みのPython 3.10を指定しています。

:::note warn
[ドキュメント](https://rye-up.com/guide/installation/#installing-rye)にもある通り、ここで指定できるのは、CPythonの3.9～3.11のみとのことなので、注意してください。
:::

:::note info
Ryeのソースコード上で、ダウンロードを実行する箇所は以下です。将来的には、この辺りがうまく修正されれば指定できるようになるかと思います。

https://github.com/mitsuhiko/rye/blob/26931a97776e25ca34aab0c54e5d0ba67d53ee5d/rye/src/bootstrap.rs#L393-L454
:::

### 手動でPythonをダウンロードした後に、Ryeをインストール

それでは、**`RYE_TOOLCHAIN`に手動でダウンロードしたPythonを指定した後、再度Ryeのインストールを実行**し、先ほどのエラーが発生しないかを確認します。

まず、初めに、https://github.com/indygreg/python-build-standalone/releases から、Python 3.11.6をzst形式でダウンロードし、それを解凍した後、`C:\hogehoge\cpython-3.11-manual\`に配置します。

```title: 配置後のディレクトリ構成（抜粋）
cpython-3.11-manual
├── build
├── install
    └── python.exe
├── licenses
└──PYTHON.json
```

その後、以下を実行し、Ryeをインストールします。

```
set RYE_TOOLCHAIN=C:\hogehoge\cpython-3.11-manual\install\python.exe
set RYE_HOME=C:\hogehoge\rye
rye-x86_64-windows.exe
```

`RYE_TOOLCHAIN`には、先ほど配置した`C:\hogehoge\cpython-3.11-manual\install\python.exe`を指定します。

実行結果は以下の通りです。
```title: 実行結果
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:\hogehoge\rye
This path can be changed by exporting the RYE_HOME environment variable.

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

Continue? yes
Installed binary to C:\hogehoge\rye\shims\rye.exe
Registering toolchain at C:\hogehoge\rye\py\cpython-3.11-manual\install\python.exe
Registered toolchain as cpython@3.11.6
Bootstrapping rye internals
Found a compatible python version: cpython@3.11.6
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 407 Proxy Authentication Required'))': /simple/pip/

------------------省略------------------

ERROR: No matching distribution found for pip==23.1
error: failed to initialize virtualenv (upgrade pip)
Press any key to continue

```

今度は別のエラーが発生しました。具体的には、pipのインストールの際に`ProxyError`が発生しています。これは、単に**環境変数`HTTPS_PROXY`を指定する**ことで、解決できます。

```
set RYE_TOOLCHAIN=C:\hogehoge\cpython-3.11-manual\install\python.exe
set RYE_HOME=C:\hogehoge\rye
set HTTPS_PROXY=<プロキシURL>
rye-x86_64-windows.exe
```
```title: 実行結果
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:\hogehoge\rye
This path can be changed by exporting the RYE_HOME environment variable.

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

Continue? yes
Installed binary to C:\hogehoge\rye\shims\rye.exe
Registering toolchain at C:\hogehoge\cpython-3.11-manual\install\python.exe
Registered toolchain as cpython@3.11.6
Bootstrapping rye internals
Found a compatible python version: cpython@3.11.6
Upgrading pip
Installing internal dependencies
Updated self-python installation at C:\hogehoge\rye\self

Note: You need to manually add %USERPROFILE%\.rye to your PATH.
For more information read https://mitsuhiko.github.io/rye/guide/installation

All done!
Press any key to continue
```

やっと、エラー無くRyeをインストールすることができました。それでは、実際にRyeを使ってみたいと思います。 

## rye init: プロジェクトを作成

`rye init`によって、**カレントディレクトリにプロジェクトを作成する**ことができます。
```
rye init
```
以下が出力されたら成功です。（ 以下は、`C:\test_rye\.`での実行結果です。）
```title: 実行結果
success: Initialized project in C:\test_rye\.
  Run `rye sync` to get started
```

`rye init`によって、デフォルトでは以下のようなディレクトリ構成のプロジェクトが作成されます。
```
test_rye
├── .git
├── .gitignore
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── my_project
        └── __init__.py
```

特に、**`pyproject.toml`がライブラリのバージョン等を管理**し、**`.python-version`がプロジェクト内でのPythonのバージョンを管理**します。具体的に、それぞれのファイルの内容は以下の通りでした。

```title: pyproject.toml
[project]
name = "test-rye"
version = "0.1.0"
description = "Add your description here"
authors = [
    { name = "hogehoge", email = "hogehoge@hogehoge.jp" }
]
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

```
```title: .python-version
cpython-x86_64-windows@3.12.0
```
`.python-version`より、Ryeの`0.15.2`では、Pythonのバージョンとして`3.12.0`が指定されるようです。

## rye add: ライブラリを追加

`rye add`によって**ライブラリをプロジェクトに追加**できます。
例えば、以下を実行し、numpyを追加します。
```
rye add numpy
```

これにより、`pyproject.toml`の`dependencies`にnumpyの記述が追加されます
```title: pyproject.toml
[project]
name = "test-rye"
version = "0.1.0"
description = "Add your description here"
authors = [
    { name = "hogehoge", email = "hogehoge@hogehoge.jp" }
]
dependencies = [
    "numpy>=1.24.4",
]
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

```

なお、poetryとは異なり、**`rye add`の実行だけでは、ライブラリのインストールは実行されない点**に注意してください。（後述の`rye sync`の実行時にインストールされます。）

## rye pin: プロジェクト内のPythonバージョンを指定

`rye pin`によって、**プロジェクト内で利用するPythonバージョンを変更**できます。
ここでは、Ryeのインストール時にダウンロードした内部用のPythonに合わせて、`3.11.6`を指定します。
```
rye pin 3.11.6
```

これにより、`.python-version`も以下のように変更されます。
```title: .python-version
3.11.6
```

:::note info
上記はCPythonの例です。他にPyPyも指定可能ですが、この記事ではCPythonしか扱いません。PyPyの指定方法の詳細は[ドキュメント](https://rye-up.com/guide/toolchains/pypy/)を参照してください。
:::

## rye sync: 指定したバージョンのPythonバイナリとライブラリをインストール

`rye sync`の実行によって、**指定したバージョンのPythonバイナリやライブラリをインストールし、仮想環境を作成**します。

まず、`rye sync`の前にプロキシの設定を済ませておきます。
環境変数`HTTP_PROXY`、`HTTPS_PROXY`が設定されていればOKですが、**``rye config``** によって、環境変数とは別のプロキシを指定することもできます。

```
rye config --set proxy.http=<プロキシのURL>
rye config --set proxy.https=<プロキシのURL>
```
以上を実行すると、`%RYE_HOME%\config.toml`が以下のようになるかと思います。
```title: config.toml
[proxy]
http = <プロキシのURL>
https = <プロキシのURL>
```
その後、`rye sync`を実行します。結果は以下の通りです。
なお、Pythonの`3.11.6`はRyeのインストール時にダウンロード済みなので、以下ではPythonバイナリのダウンロードはスキップされているようです。
```title: 実行結果
Initializing new virtualenv in C:\test_rye\.venv
Python version: cpython@3.11.6
Generating production lockfile: C:\test_rye\requirements.lock
Creating virtualenv for pip-tools
Generating dev lockfile: C:\test_rye\requirements-dev.lock
Installing dependencies
Looking in indexes: https://pypi.org/simple/
Obtaining file:///. (from -r C:\hogehoge\vscode\data\tmp\tmpobcr459e (line 1))
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Collecting numpy==1.26.2 (from -r C:\hogehoge\vscode\data\tmp\tmpobcr459e (line 2))
  Using cached numpy-1.26.2-cp311-cp311-win_amd64.whl (15.8 MB)
Building wheels for collected packages: test-rye
  Building editable for test-rye (pyproject.toml) ... done
  Created wheel for test-rye: filename=test_rye-0.1.0-py3-none-any.whl size=1064 sha256=fb5f3f3601d674cb018161c9a46cb2db4cb127f9246446a27609026e5c582573
  Stored in directory: C:\hogehoge\vscode\data\tmp\pip-ephem-wheel-cache-t8f6dp7x\wheels\97\54\f5\d849319cdfa096e074df352654ee2e7c919da8951f090690c6
Successfully built test-rye
Installing collected packages: test-rye, numpy
Successfully installed numpy-1.26.2 test-rye-0.1.0
Done!
```
以上により、`.venv`の他、`requirements.lock`や`requirements-dev.lock`が生成されます。

その後、仮想環境に入り、numpyが実行できることを確認します。
```
.venv\Scripts\activate
python -c "import numpy as np; print(np.array([1, 2, 3, 4, 5]))"
```
```title: 実行結果
[1 2 3 4 5]
```

うまく実行できました！

## ダウンロードされていないバージョンのPythonを指定してみる

先ほどの実行では、インストール済みのPythonのバージョン（`3.11.6`）を指定しましたが、次に、**ダウンロードされていないバージョン**を指定し、再度`rye sync`を実行してみます。

具体的には、以下を実行します。ここでは、`3.12`を指定しています。
```
rye pin 3.12
rye sync
```

```title: 実行結果
Python version mismatch (found cpython@3.11.6, expect cpython@3.12.0), recreating.
Downloading cpython@3.12.0
error: failed fetching toolchain ahead of sync

Caused by:
    0: download of https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.12.0%2B20231002-x86_64-pc-windows-msvc-shared-pgo-full.tar.zst failed
    1: [35] SSL connect error (schannel: next InitializeSecurityContext failed: Unknown error (0x80092012))
```

例のSSLエラーが発生しました。
そこで、**Ryeのインストール時と同様に手動でダウンロード**して、Ryeに読み込ませたいと思います。しかし、Ryeのインストール時とは異なり、`RYE_TOOLCHAIN`のような環境変数は用意されてなさそうなので、ここは、気合で指定します。

具体的には、**`%RYE_HOME%\py` に配置**します。また、**ディレクトリ名も`cpython@major.minor.patch`** にする必要があります。（このようにしないと、読み込まれませんでした。）

本記事の例では、`%RYE_HOME%`が`C:\hogehoge\rye`であるため、以下のようなディレクトリ配置になりました。
```title: 配置後のディレクトリ構成（抜粋）
C:\hogehoge\rye
└──cpython@3.12.0
    ├── build
    ├── install
        └── python.exe
    ├── licenses
    └──PYTHON.json
```
:::note warn
以上はドキュメントに未掲載のやり方なので、今後の更新次第では実行できなくなる可能性があることに注意してください。
:::

その後再び以下を実行します。
```
rye pin 3.12
rye sync
```

```title:実行結果
Python version mismatch (found cpython@3.11.6, expect cpython@3.12.0), recreating.
Initializing new virtualenv in C:\test_rye\.venv
Python version: cpython@3.12.0
Generating production lockfile: C:\test_rye\requirements.lock
Creating virtualenv for pip-tools
Generating dev lockfile: C:\test_rye\requirements-dev.lock
Installing dependencies
Looking in indexes: https://pypi.org/simple/
Obtaining file:///. (from -r C:\hogehoge\vscode\data\tmp\tmppk6qzwp2 (line 1))
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Collecting numpy==1.26.2 (from -r C:\hogehoge\vscode\data\tmp\tmppk6qzwp2 (line 2))
  Downloading numpy-1.26.2-cp312-cp312-win_amd64.whl (15.5 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 15.5/15.5 MB 5.9 MB/s eta 0:00:00
Building wheels for collected packages: test-rye
  Building editable for test-rye (pyproject.toml) ... done
  Created wheel for test-rye: filename=test_rye-0.1.0-py3-none-any.whl size=1064 sha256=fb5f3f3601d674cb018161c9a46cb2db4cb127f9246446a27609026e5c582573
  Stored in directory: C:\hogehoge\vscode\data\tmp\pip-ephem-wheel-cache-cykv_nx_\wheels\8b\19\c8\73a63a20645e0f1ed9aae9dd5d459f0f7ad2332bb27cba6c0f
Successfully built test-rye
Installing collected packages: test-rye, numpy
Successfully installed numpy-1.26.2 test-rye-0.1.0
Done!
```

Python `3.12.0`を読み込ませることに成功したようです。ログを見ると、Pythonバージョンを変えると、`.venv`らが再構築されていることがわかると思います。

なお、Pythonのダウンロードはバージョンごとに一度でOKなので、以降はPythonの`3.11.6`と`3.12.0`はプロキシを気にせずに行き来することができるはずです。

Ryeの機能は他にもいろいろありますが、基本的な機能は紹介しましたので、本記事はここで以上にしたいと思います。


# まとめ

本記事では、**Pythonのパッケージ管理ツールであるRye**を紹介し、また、**社内プロキシ環境で使う上で躓いた点とどう対処したか**についても紹介しました。やや、力技で解決したところもあり恐縮ですが、そこは、今後の更新に期待したいと思います。

何か、不明点、間違っている点があれば気軽にコメントでご指摘ください。