Pipenv入門

背景

前回Dockerでモジュールを利用するにはdocker volumeを利用する必要があるということを記載しました。

pythonのモジュール管理でPipenvというRubyのbundlerに似ているツールがあるということで、これを調べてみようと思います。

Pipenvとは

ドキュメントにはこう記載されています。

Pipenv は、全てのパッケージングの世界 (bundler、composer、npm、cargo、yarnなどなど。) における最高のものをPythonの世界にもたらすことを目的としたツールです。

また、以下のようにも書いてあります。

Pipenvは、手動でパッケージのインストールおよびアンインストールを行うのと同じように Pipfile に対してパッケージの追加および削除を行うのに加え、自動でプロジェクト用の仮想環境を作成し管理します。 またPipenvは、いかなるときも重要な Pipfile.lock を生成し、これを利用しビルドが常に同じ結果になるようにします。

ほぼRubyのbundlerと一緒ですかね。では実際に使ってみます。

Pipenvのインストール

以前利用していたDockerの環境でインストールしてみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ docker-compose run --rm web pip install pipenv
Starting django_db_1 ... done
Creating django_web_run ... done
Collecting pipenv
Downloading pipenv-2021.5.29-py2.py3-none-any.whl (3.9 MB)
|████████████████████████████████| 3.9 MB 107 kB/s
Collecting certifi
Downloading certifi-2021.5.30-py2.py3-none-any.whl (145 kB)
|████████████████████████████████| 145 kB 180 kB/s
Collecting virtualenv-clone>=0.2.5
Downloading virtualenv_clone-0.5.6-py3-none-any.whl (6.6 kB)
Requirement already satisfied: setuptools>=36.2.1 in /usr/local/lib/python3.9/site-packages (from pipenv) (57.0.0)
Requirement already satisfied: pip>=18.0 in /usr/local/lib/python3.9/site-packages (from pipenv) (21.1.3)
Collecting virtualenv
Downloading virtualenv-20.6.0-py2.py3-none-any.whl (5.3 MB)
|████████████████████████████████| 5.3 MB 189 kB/s
Collecting backports.entry-points-selectable>=1.0.4
Downloading backports.entry_points_selectable-1.1.0-py2.py3-none-any.whl (6.2 kB)
Collecting distlib<1,>=0.3.1
Downloading distlib-0.3.2-py2.py3-none-any.whl (338 kB)
|████████████████████████████████| 338 kB 91 kB/s
Collecting filelock<4,>=3.0.0
Downloading filelock-3.0.12-py3-none-any.whl (7.6 kB)
Collecting six<2,>=1.9.0
Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting platformdirs<3,>=2
Downloading platformdirs-2.2.0-py3-none-any.whl (13 kB)
Installing collected packages: six, platformdirs, filelock, distlib, backports.entry-points-selectable, virtualenv-clone, virtualenv, certifi, pipenv
Successfully installed backports.entry-points-selectable-1.1.0 certifi-2021.5.30 distlib-0.3.2 filelock-3.0.12 pipenv-2021.5.29 platformdirs-2.2.0 six-1.16.0 virtualenv-20.6.0 virtualenv-clone-0.5.6
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.1.3; however, version 21.2.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.

無事インストールできましたが、警告が2つほど出てますね。pipは結構頻繁にアップデートするんですかね?とりあえずアップデートしておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker-compose run --rm web pip install --upgrade pip
Creating django_web_run ... done
Requirement already satisfied: pip in /usr/local/lib/python3.9/site-packages (21.1.3)
Collecting pip
Downloading pip-21.2.1-py3-none-any.whl (1.6 MB)
|████████████████████████████████| 1.6 MB 39 kB/s
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 21.1.3
Uninstalling pip-21.1.3:
Successfully uninstalled pip-21.1.3
Successfully installed pip-21.2.1
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

アップグレードできました。

念のため一覧表示で確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ docker-compose run --rm web pip list
Creating django_web_run ... done
Package Version
--------------------------------- ---------
asgiref 3.3.4
backports.entry-points-selectable 1.1.0
certifi 2021.5.30
distlib 0.3.2
Django 3.2.4
filelock 3.0.12
mysqlclient 2.0.3
pip 21.2.1
pipenv 2021.5.29
platformdirs 2.2.0
pytz 2021.1
setuptools 57.0.0
six 1.16.0
sqlparse 0.4.1
virtualenv 20.6.0
virtualenv-clone 0.5.6
wheel 0.36.2

無事Pipenvもインストールされています。バージョン番号が年月日なんですね。

Pipfileの作成

ではPipfileを作成します。こちらによると、requirements.txtがあれば、その内容からPipfileを作成してくれるようです。やってみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ docker-compose run --rm web python -m pipenv install
Creating django_web_run ... done
Creating a virtualenv for this project...
Pipfile: /code/Pipfile
Using /usr/local/bin/python3.9 (3.9.5) to create virtualenv...
⠇ Creating virtual environment...created virtual environment CPython3.9.5.final.0-64 in 518ms
creator CPython3Posix(dest=/root/.local/share/virtualenvs/code-_Py8Si6I, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
added seed packages: pip==21.1.3, setuptools==57.1.0, wheel==0.36.2
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

✔ Successfully created virtual environment!
Virtualenv location: /root/.local/share/virtualenvs/code-_Py8Si6I
requirements.txt found, instead of Pipfile! Converting...
✔ Success!
Warning: Your Pipfile now contains pinned versions, if your requirements.txt did.
We recommend updating your Pipfile to specify the "*" version, instead.
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Updated Pipfile.lock (1644d3)!
Installing dependencies from Pipfile.lock (1644d3)...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 00:00:04
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.

実行が終わりました。PipfilePipfile.lockも作成されています。

virtualenvについて

出力されたメッセージをみていて、気になる点がいくつかあります。

1
2
✔ Successfully created virtual environment! 
Virtualenv location: /root/.local/share/virtualenvs/code-_Py8Si6I

仮想環境を作成したと表示がありますが、仮想環境はdocker volumeを使っていないので消えてしまっている可能性が高いです。確認してみます。

仮想環境のパスを確認するコマンドがあるようなのでそれを実行してみます。

1
2
3
4
$ docker-compose run --rm web python -m pipenv --venv
Creating django_web_run ... done
No virtualenv has been created for this project(/code) yet!
Aborted!

やはりダメでした…仮想環境を使わずにインストールする方法はないかと探してみたところ、--systemというオプションがあるようです。

https://pipenv-ja.readthedocs.io/ja/translate-ja/basics.html#pipenv-install

やってみます

1
2
3
4
$ docker-compose run --rm web python -m pipenv install --system
Creating django_web_run ... done
Installing dependencies from Pipfile.lock (1644d3)...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 0

先ほどインストールしたのでインストール済だからでしょうか。パッケージがインストールされた感じはありません。一度全てアンインストールしてみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ docker-compose run --rm web python -m pipenv uninstall --system --all
Creating django_web_run ... done
Creating a virtualenv for this project...
Pipfile: /code/Pipfile
Using /usr/local/bin/python3.9 (3.9.5) to create virtualenv...
⠇ Creating virtual environment...created virtual environment CPython3.9.5.final.0-64 in 521ms
creator CPython3Posix(dest=/root/.local/share/virtualenvs/code-_Py8Si6I, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
added seed packages: pip==21.1.3, setuptools==57.1.0, wheel==0.36.2
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

✔ Successfully created virtual environment!
Virtualenv location: /root/.local/share/virtualenvs/code-_Py8Si6I
Un-installing all [dev-packages] and [packages]...
Found 0 installed package, skip purging.
Environment now purged and fresh!

なぜか仮想環境が立ち上がってしまっています…アンインストール時は--systemオプションを正しく反映できてないようです…

仕方ないので、pipコマンドでアンインストールしてみます

1
2
3
4
5
6
7
8
9
10
11
12
$ docker-compose run --rm web python -m pip uninstall django
Creating django_web_run ... done
Found existing installation: Django 3.2.4
Uninstalling Django-3.2.4:
Would remove:
/usr/local/bin/django-admin
/usr/local/bin/django-admin.py
/usr/local/lib/python3.9/site-packages/Django-3.2.4.dist-info/*
/usr/local/lib/python3.9/site-packages/django/*
Proceed (Y/n)? Y
Successfully uninstalled Django-3.2.4
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

アンインストールできたかどうかを確認します

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ docker-compose run --rm web python -m pip list
Creating django_web_run ... done
Package Version
--------------------------------- ---------
asgiref 3.4.1
backports.entry-points-selectable 1.1.0
certifi 2021.5.30
distlib 0.3.2
filelock 3.0.12
mysqlclient 2.0.3
pip 21.2.1
pipenv 2021.5.29
platformdirs 2.2.0
pytz 2021.1
setuptools 57.0.0
six 1.16.0
sqlparse 0.4.1
virtualenv 20.6.0
virtualenv-clone 0.5.6
wheel 0.36.2

djangoがなくなっていることがわかります。では--systemオプションを指定してインストールしてみましょう。

1
2
3
4
$ docker-compose run --rm web python -m pipenv install --system
Creating django_web_run ... done
Installing dependencies from Pipfile.lock (1644d3)...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 1/1 —

インストールされたことを確認します

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ docker-compose run --rm web python -m pip list
Creating django_web_run ... done
Package Version
--------------------------------- ---------
asgiref 3.4.1
backports.entry-points-selectable 1.1.0
certifi 2021.5.30
distlib 0.3.2
Django 3.2.4
filelock 3.0.12
mysqlclient 2.0.3
pip 21.2.1
pipenv 2021.5.29
platformdirs 2.2.0
pytz 2021.1
setuptools 57.0.0
six 1.16.0
sqlparse 0.4.1
virtualenv 20.6.0
virtualenv-clone 0.5.6
wheel 0.36.2

アンインストール時はpip uninstallで行うのがよさそうです

Pipenvを利用した開発フロー

Pipfile, Pipfile.lockの扱い

Pipfile、Pipfile.lockはソースコード管理ツールで管理するのがよさそうです。初めてプロジェクトをチェックアウトしたメンバーはこれらのファイルを元にpipenv installを行います。こちらにも記載があります。

開発環境と本番環境

開発環境では--devオプションを指定、本番環境では指定しないようにします。

Docker環境でのインストール

Docker環境ではシステムのpipを利用すればよいので、pipenv install --systemとします。すると、Pipfile.lockの内容でインストールが行われます。ただし、アンインストールができないので、その場合はpip uninstall パッケージ名とします。

まとめ

Pythonのパッケージ管理ツールのPipenvについて調べてみました。

Dockerで利用するのが前提だったため、仮想環境を用いないオプションを探したりするのに少し時間がかかりました(ドキュメントを読むのは大事ですね)。また、アンインストールがうまくいかない点などスムーズにいかない点がいくつかありました。

Rubyに慣れている自分にとっては、Pythonのパッケージ管理システムは難しかったです。bundlerさえわかっていれば済むRubyは素敵だなと思いました。Pythonのパッケージ管理システムはまだ発展途上という感じでしょうか。

当面はPipenvを使ってチーム開発を行なっていこうと思います。