2018/02/20

ライブラリ: Pipenv



Python のパッケージ管理用のライブラリ「 Pipenv 」をご紹介します。

$ pipenv


Pipenv とは


Pipenv (読み方は「ピップエンブ」)は Python のパッケージ(≒ライブラリ)をプロジェクト単位で管理するためのライブラリです。 Requests の作者として有名な Kenneth Reitz 氏 によるプロジェクトで、 2017 年にスタートしたようです。

pip や virtualenv を裏で組み合わせて、よりよい DX (Developer eXperience) を提供するライブラリです。 Pipenv を導入すれば、プロジェクトのパッケージ管理において pip や virtualenv のコマンドを打つ必要がなくなります。

公式のドキュメントでは次のような説明がされています。

Pipenv — the officially recommended Python packaging tool from Python.org, free (as in freedom).

Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. Windows is a first–class citizen, in our world.

It automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your Pipfile as you install/uninstall packages. It also generates the ever–important Pipfile.lock, which is used to produce deterministic builds.

少し長いですが、以下、意訳です。

Pipenv — Python.org で公式に推奨されている Python パッケージングツール。フリー(「自由」という意味で)。

Pipenv はパッケージングの世界( bundler / composer / npm / cargo / yarn 等)のいいとこ取りをすることを目的としたツールです。 Windows は、 Pipenv の世界では第一級市民です。

Pipenv は、あなたのプロジェクトの virtualenv を自動的に作成・管理し、あなたがパッケージをインストールまたはアンインストールしたときに Pipfile へのパッケージの追加や削除も行います。まったく共通のビルドを行うために使われる、非常に重要な Pipfile.lock の生成も行います。

イメージとしては、公式の説明のとおり、他のプログラミング言語で定番となっている各種パッケージ管理ツールと近い使用感で使えるパッケージマネージャーです。 npmyarnbundlecomposer 等のコマンドに馴染みのある方であれば抵抗なくすぐに使い始められるのではないかと思います。

Pipenv の特徴のまとめ


Pipenv の主な特徴をかんたんにまとめると次のとおりです。

  • プロジェクト単位でパッケージのインストール・アンインストールが行える
  • プロジェクト単位のパッケージは、ユーザ毎に virtualenv をまとめたディレクトリの下にインストールされ一元管理される
  • インストールされたパッケージの情報は Pipenv ファイルと Pipenv.lock ファイルに記録される
  • Pipenv にはインストールを実行した人が指定したパッケージのバージョンが記録される
  • Pipenv.lock には Pipenv が実際にインストールをしたパッケージのバージョンが記録される
  • PipenvPipenv.lock を共有すると、同じバージョンのパッケージをインストールしたプロジェクト環境がかんたんに再現できる
  • 環境変数を定義した .env ファイルが存在する場合はその中身が virtualenv 上で読み込まれる

私は個人的には「 Python のプロジェクト毎のライブラリを npm や yarn 風に管理できる、 pip と virtualenv の統合ラッパー」といったイメージを持っています。

Pipenv の基本的な使い方


すべての使い方をここで網羅するのは難しいので、基本的な使い方のみをご紹介します。

その他の基本的な使い方は pipenv--help オプションで、より詳細の使い方は公式のドキュメントで確認ができるので、詳しく知りたい方は 公式のドキュメント 等をご参照ください。

Pipenv のインストール

まずはインストール方法から見ていきましょう。前提として、 Python 3 と pip がインストールされているものとします。

$ pip install pipenv

pipenv コマンドが使えるようになれば、インストールは成功です。

$ pipenv --version
pipenv, version 9.0.3

Pipenv によるプロジェクト単位のパッケージ環境( virtualenv )の作成

Pipenv はプロジェクト単位で利用するものなので、続いて、プロジェクトのルートディレクトリを作りましょう。

$ mkdir myproject
$ cd myproject/

プロジェクトの中で Pipenv を初期化します。

$ pipenv --python 3.6
Creating a virtualenv for this project…
Using /usr/local/bin/python3.6m to create virtualenv…
⠋Running virtualenv with interpreter /usr/local/bin/python3.6m
Using base prefix '/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy/bin/python3.6
Also creating executable in /Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy/bin/python
Installing setuptools, pip, wheel...done.

Virtualenv location: /Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy
Creating a Pipfile for this project…

補足ですが、このコマンドを実行したときの私の環境では、 Homebrew を使ってインストールした Python 3.6 が /usr/local/bin/python3.6m に、そこから作った virtualenv が /Users/hayato/.local/bin にいて、それらを使って Pipenv を実行しています。

上の出力からわかるとおり、最初に myproject の後に - を付けてランダムな文字列(?)をつなげた virtualenv ディレクトリの下に virtualenv が作成され、 setuptoolspipwheel の 3 つのライブラリがインストールされた virtualenv が作成されました。そして最後に Pipfile (読み方は「ピップファイル」)が作成されました。

ちなみに、このプロジェクトのルートディレクトリ myproject はデスクトップにあり、上の ~/.local/share/virtialenvs ディレクトリとは無関係の場所にいます。

上のコマンドが成功したら、カレントディレクトリに Pipfile ファイルが作られているはずです。

$ cat Pipfile

中身は次のとおりで、最小限のプロジェクト情報を格納したファイルとなっています(このあたりは Pipenv のバージョンが上がると変わる可能性があります。参考にされる際はご注意ください)。

[[source]]

url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"


[packages]



[dev-packages]



[requires]

python_version = "3.6"

virtualenv の場所はコマンドで確認したりすることができます。

pipenv --venv
/Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy

パッケージのインストール

プロジェクトのパッケージ環境を格納する virtualenv が用意できたら、自由にパッケージをインストールできます。方法は pip の場合と同様です。

pipenv コマンドにサブコマンド install を指定してパッケージ名を指定します。

$ pipenv install Django
Installing Django…
Collecting Django
  Using cached Django-2.0.2-py3-none-any.whl
Collecting pytz (from Django)
  Using cached pytz-2018.3-py2.py3-none-any.whl
Installing collected packages: pytz, Django
Successfully installed Django-2.0.2 pytz-2018.3

Adding Django to Pipfile's [packages]…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (374a8f)!

処理が無事に完了すると、プロジェクトのルートディレクトリにある Pipfile ファイルが更新され、同じ場所に Pipfile.lock ファイルが生成されます。

中身を確認してみましょう。 Pipfile ファイルの中の [packages] の下に django の行が追加されました。

[packages]

django = "*"

Pipfile.lock の方には、実行した環境のさまざまな情報と、実際にインストールされたパッケージの情報が記述されています。

同じ要領で他のパッケージも続けてインストールしていくとよいでしょう。

$ pipenv install requests
$ pipenv install mysqlclient
$ pipenv install uwsgi

もちろん、バージョンを指定してインストールすることも可能です。

$ pipenv install django==1.11

完全一致は == 、互換性維持は ~= といった感じで、バージョン指定の方法には pip と同じものが使えるようです(こちらもバージョンが上がると変わる可能性があるので、参考にされる際はご注意ください)。

実際のプロジェクトでは、 PipfilePipfile.lock を Git (等の VCS )の管理下に置くことで、複数人や複数の環境でコードを共用するときに同一のパッケージ環境をかんたんに共有できるようになります。

ここまで読んだときに、 Python 歴が長い方や pip に詳しい方であれば「あれ、 pip + requirements.txt と何がちがうんだろう・・・」とお思いのことかと思います。このあたりについては、説明したいのですが・・・すみません、私には正確な説明ができないので、「 pip + requirements.txt 」の課題について Kenneth Reitz 氏が語った次の記事を参照していただければと思います。


パッケージのアップデート

すでにインストールされたパッケージをアップデートしたい場合は、サブコマンド update を使用します。

$ pipenv update django

パッケージのアンインストール

インストールされたパッケージをアンインストールするには、サブコマンド uninstall を使用します。

$ pipenv uninstall django

Pipfile 入りのプロジェクトの依存関係のインストール

誰か他の人が作った、 Pipfile ファイルが含まれたプロジェクトにおいて、依存関係をインストールするには pipenv install コマンドを実行します。

$ pipenv install

virtualenv の有効化

Pipenv でインストールされたパッケージは virtualenv の中にいるので、そのままでは利用できません。利用するには virtualenv を有効化する必要があります。

Pipenv が作成した virtualenv を有効にするには pipenv shell コマンドを利用します。

$ pipenv shell
Spawning environment shell (/usr/local/bin/bash). Use 'exit' to leave.
Loading init files ........... done!
source /Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy/bin/activate

無事に virtualenv が有効化できたら、 Python のパスが virtualenv のものになり、インストールしたパッケージが利用できることが確認できるでしょう。

(myproject-abX3VXqy) $ which python
/Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy/bin/python

(myproject-abX3VXqy) $ pip freeze | grep requests
requests==2.18.4

(myproject-abX3VXqy) $ django-admin startproject projectX .

virtualenv を有効化しているうちはコマンドプロンプトの前に ( virtualenv 名) が付くので、 virtualenv が有効になっているかどうかはそこで確認することができます。

有効になった virtualenv を無効にして元に戻るには、 exit コマンドを使います。もちろん、 exit のショートカット、たとえば MacOS なら ctrl + d を使うこともできます。

(myproject-abX3VXqy) $ exit
$

virtualenv を有効にしてコマンドを実行

特定のコマンドを実行するときだけ virtualenv を利用したい場合はサブコマンド run を使います。

$ # Pipenv で管理されている virtualenv を利用して `django-admin` コマンドを実行する
$ pipenv run django-admin startproject projectX .

$ # Pipenv で管理されている virtualenv を利用して `manage.py` ファイルを実行する
$ pipenv run app/manage.py runserver

他の言語のパッケージマネージャではそれぞれ次のコマンドに相当するイメージです(間違えていたらすみません・・・)。

Bundler (Ruby):

$ bundle exec rails ...

Npm (Node):

$ ./node_modules/.bin/ava

Composer (PHP):

$ composer run phpunit ...

virtualenv の削除

Pipenv で作成した virtualenv が不要になったら、 virtualenv を削除しましょう。

削除は他のサブコマンドとは少しちがって、 pipenv コマンドに --rm オプションを渡して実行する形になっています。

$ pipenv --rm
Removing virtualenv (/Users/hayato/.local/share/virtualenvs/myproject-abX3VXqy)…

個人的には、 virtualenv は削除し忘れることがよくあるので、一元管理されているディレクトリをときどきチェックして不要になったものがないか確認するようにしています。

Pipenv でのオートコンプリートの有効化

Pipenv にはサブコマンドのオートコンプリート(自動補完)機能が付いています。

pipenv --completion を実行するとオートコンプリートを有効にするスクリプトが出力されるので、もしオートコンプリートを利用したいなら .bashrc などで用意するようにしておくとよいでしょう。

ちなみに、私の Bash で実行すると次のように出力されました。

$ pipenv --completion

_pipenv_completion() {
    local IFS=$'\t'
    COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
                   COMP_CWORD=$COMP_CWORD \
                   _PIPENV_COMPLETE=complete-bash $1 ) )
    return 0
}

complete -F _pipenv_completion -o default pipenv

以上です。

Pipenv には、今回は取り上げなかった機能として次のようなもの等もあります。

  • 既知の脆弱性のチェック( safety を利用)
  • Flake8 のスタイル違反のチェック
  • 使われていない可能性のあるパッケージのチェック

より詳しく知りたい方は公式ドキュメントをご覧になってみてください。

参考


日本語

こちらの記事はとてもわかりやすいです。

英語

いずれも Kenneth Reitz 氏本人の公式ドキュメント / 公式ページですが、これがいちばんわかりやすい気がします。

追記 2018/05/17


Python コミュニティのイベント PyCon 2018 で Kennth 氏本人が Pipenv についての発表をしていました。 Python のパッケージ管理の歴史を絡めてなぜ Pipenv を開発するに至ったのかの話や実演デモを行っています。とてもわかりやすくておすすめです。

2 件のコメント:

なりと さんのコメント...

非常にわかりやすかったです。ありがとうございます。

後藤隼人 さんのコメント...

なりとさん

ご丁寧にコメントいただきありがとうございます!

もしお気づきの点等がございましたらお気軽にご指摘いただければと思います :)