rye を使ったPythonの開発環境を VSCode Dev Container で構築する
rye がよさそう
Rye は、Rust の Rustup と Cargo からインスピレーションを得て、Python に新しいタイプのパッケージング エクスペリエンスを構築する実験的な取り組みです。まだ製品化の準備ができていませんが、フィードバックや提案をいただければ幸いです。
個人的にも Python にはよくお世話になっておりますが、ざっくり印象として「バージョン管理が面倒」「パッケージ管理が面倒」[1] 「それらのためのツールがいくつか並立している」という課題というか、悩み事が常についてまわっていると思ってまして、実際にプロジェクトで使う際にも、その時点その時点でのベストプラクティスを調べつつ、環境を構築しているというのが実態でした。[2]
実験的な取り組みは大好物なので、さっそく試してみます。
Dev Container を作る
私はよくやりがちですが、自分のマシンにいろいろインストールしたくないので、できることはすべて Dev Container でやろうとします。今回もこれでいきます。
{
"name": "rye-workspace",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": [
"gruntfuggly.todo-tree",
"eamodio.gitlens",
"ryokat3.vscode-qiita-markdown-preview",
"christian-kohler.path-intellisense",
"ms-azuretools.vscode-docker",
"ms-python.python",
"ms-toolsai.jupyter"
]
}
},
"remoteUser": "vscode",
"postCreateCommand": "/bin/sh .devcontainer/postCreateCommand.sh"
}
FROM mcr.microsoft.com/devcontainers/base:bullseye
RUN apt-get update \
&& apt-get install -y libwebkit2gtk-4.0-dev libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev git vim curl bash \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
#!/bin/bash
curl -sSf https://rye-up.com/get | RYE_INSTALL_OPTION="--yes" bash
echo 'source "$HOME/.rye/env"' >> ~/.bashrc
. "$HOME/.rye/env"
Dockerfileについて
こちらの記事でも書きましたが、実際にはbashプロンプトをいろいろ便利にするためにコマンドをいくつか追加しています。手元のDockerfileの全体像は以下のようになっています。ご参考まで🙇
FROM mcr.microsoft.com/devcontainers/base:bullseye
RUN apt-get update \
&& apt-get install -y libwebkit2gtk-4.0-dev libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev git vim curl bash \
&& apt-get clean -y && rm -rf /var/lib/apt/lists/*
RUN echo "source /usr/share/bash-completion/completions/git" >> ~/.bashrc
WORKDIR /usr/share/bash-completion/completions
RUN curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
RUN curl -O https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash
RUN chmod a+x git*.*
RUN ls -l $PWD/git*.* | awk '{print "source "$9}' >> ~/.bashrc
RUN echo "GIT_PS1_SHOWDIRTYSTATE=true" >> ~/.bashrc
RUN echo "GIT_PS1_SHOWUNTRACKEDFILES=true" >> ~/.bashrc
RUN echo "GIT_PS1_SHOWUPSTREAM=auto" >> ~/.bashrc
RUN echo 'export PS1="\[\033[01;32m\]\u@\h\[\033[01;33m\] \w \[\033[01;31m\]\$(__git_ps1 \"(%s)\") \\n\[\033[01;34m\]\\$ \[\033[00m\]"' >> ~/.bashrc
devcontainer.json
のextentions
は、お好みのものをよしなに並べてください。
rye
の環境構築を Dev Container にする際のポイントはdevcontainer.json
のpostCreateCommand
と、postCreateCommand.sh
です。
postCreateCommand
に指定したコマンドは、コンテナのビルド後に自動実行してくれます。公式のinstallationに沿ったインストール手順をpostCreateCommand.sh
に記述しておいて実行してもらいます。
Dev Container を起動する
上のように作成したファイルを.devcontainer
ディレクトリに格納し、Dev Container を起動します。
起動が完了したら、ターミナルでrye
のバージョンを確認してみます。
$ rye --version
rye 0.4.0
commit: 0.4.0 (cdc5c37bc 2023-05-29)
platform: linux (x86_64)
self-python: cpython@3.10
symlink support: true
無事、インストールできたようです!
rye
のコマンド紹介と実演
ここまでできれば、あとはrye
を使って開発を進めていくだけです。
公式のDocumentationにもありますが、このあと使うだろうコマンドをいくつか紹介しておきますので、ご参考ください。
- プロジェクトの作成:
rye init {project-name}
- Python インタプリタバージョンの指定:
rye pin {py-version}
- パッケージの追加指定:
rye add {package-name}
- パッケージの削除指定:
rye remove {package-name}
- 仮想環境の作成・更新、パッケージのインストール:
rye sync
pip/pipenvとの大きな違いは、rye
はsync
を実行するまでパッケージのインストールやアンインストールを行わないことです。
add
やremove
で行うのはあくまでもパッケージの内容を記載したpyproject.toml
の編集のみで、実際のパッケージ操作はrye sync
を実行して初めて行われるようになっています。
まずはプロジェクトの作成から始めます。
プロジェクトの作成
$ rye init sample-project
success: Initialized project in /workspaces/rye-template/sample-project
Run `rye sync` to get started
Python バージョンの指定
$ rye pin 3.11
pinned 3.11.3 in /workspaces/rye-template/sample-project/.python-version
この時点ではまだインストールされません。
ライブラリの指定
$ rye add pandas ipykernel matplotlib
Added pandas~=2.0.2 as regular dependency
Added ipykernel~=6.23.1 as regular dependency
Added matplotlib~=3.7.1 as regular dependency
実行環境と同じく、この時点ではインストールされません。
実行環境とライブラリのインストール
$ rye sync
Downloading cpython@3.11.3
Checking hash
success: Downloaded cpython@3.11.3
Initializing new virtualenv in /workspaces/rye-template/sample-project/.venv
Python version: cpython@3.11.3
Generating production lockfile: /workspaces/rye-template/sample-project/requirements.lock
Creating virtualenv for pip-tools
Generating dev lockfile: /workspaces/rye-template/sample-project/requirements-dev.lock
Installing dependencies
Looking in indexes: https://pypi.org/simple/
Obtaining file:///. (from -r /tmp/tmpj5_otvvd (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.24.3 (from -r /tmp/tmpj5_otvvd (line 2))
Downloading numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.3 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.3/17.3 MB 13.2 MB/s eta 0:00:00
Collecting pandas==2.0.2 (from -r /tmp/tmpj5_otvvd (line 3))
Downloading pandas-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (12.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.2/12.2 MB 12.8 MB/s eta 0:00:00
・・・中略・・・
Building wheels for collected packages: sample-project
Building editable for sample-project (pyproject.toml) ... done
Created wheel for sample-project: filename=sample_project-0.1.0-py3-none-any.whl size=1124 sha256=ad662f09eef2104b8c4f5699e8cf6c4520dd087d5da174e356f894f9e8530092
Stored in directory: /tmp/pip-ephem-wheel-cache-pu3ysosl/wheels/97/54/f5/d849319cdfa096e074df352654ee2e7c919da8951f090690c6
Successfully built sample-project
Installing collected packages: pytz, tzdata, six, sample-project, python-dateutil, pandas, numpy
Successfully installed numpy-1.24.3 pandas-2.0.2 python-dateutil-2.8.2 pytz-2023.3 sample-project-0.1.0 six-1.16.0 tzdata-2023.3
Done!
rye sync
を実行すると、Python実行環境のインストールはパッケージのダウンロードが行われます。
ここまでの作業で、pandas
、ipykernel
、matplotlib
をインストールした実行環境ができました。
せっかくなので
Jupyter Notebookをちょっと動かしてみます。最近は対話型AIや画像生成AIなどの分野で、Google Colabと合わせてとてもよく見かけるようになりました。
コマンドパレットから「Create: New Jupyter Notebook」を選択します。
新しい Notebook が開くので、
こんな感じでコードを入力してみます。
import pandas as pd
url = "https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031523105&fileKind=1"
df = pd.read_csv(url, encoding="shift-jis")
df = df.drop(df.index[-1], axis=0)
df
Run All
で実行しようとすると、実行環境を選ぶダイアログが表示されます。
rye
が構築してくれたvenvを選択します。
結果が表示されました。[4]
まとめ
以上です!
今回はrye
を使って、Python実行環境の作成・ライブラリのインストール・実際のコーディングまで試すことができました。
例えば別のマシンで同じ環境を構築したいとなったとき、rye
をインストールさえしておけば、ソースコード一式に.python-version
とpyproject.toml
だけ移してrye sync
とすると同じバージョンの環境が構築できるはずです。
今までのPython開発環境には無い、かなりの強みと利便性を感じます。
ぜひご参考いただければ幸いです。
おまけ
rye
は「ライ麦」だそうです。公式サイトのアイコンもライ麦の形をしてますね。
最後に、rye
の開発者でありFlask
の開発者でもある @mitsuhiko氏のコメントを引用して終わらせていただきます。
I just want it solved, and I want to never have to think about Python packaging and project management every again. And until there is a standard tool we all rally around, I don't see that happen.
Pythonのパッケージングやプロジェクト管理について、二度と考える必要がないようにしたいのです。そして、私たち全員が参加できる標準的なツールができるまでは、それが実現することはないでしょう。rye(またはryeのようなもの)がそれになり得るかどうかは分かりませんが、私はオファーを出しています。
ではまた!
参考記事
-
nodeなどと同様、Python インタプリタのバージョンとパッケージのバージョンは整合している必要があるので、複数人で開発する場合にはそれぞれの環境で不整合を起こさせない仕組みが必要になります。 ↩︎
-
Python 自体の管理なら venv, pyenv, Conda、パッケージなら pip, pipenv, Conda, Poetry・・・最近は「pyenv + poetry」がおすすめなんでしょうか。 ↩︎
-
新しいウィンドウもDev Container に接続した状態で開きます。このウィンドウはryeが作成した
.venv
を利用できるようになり、以降の作業がスムーズに進みます。 ↩︎ -
国勢調査による人口推移データです。 ↩︎
Discussion
との記載があったので, 一応コメントさせていただきます!