Pipenvを導入してみる

この記事は[Gunosy Advent Calendar 2017](https://qiita.com/advent-calendar/2017/gunosy)の17日目の記事です。

## requirementsで管理しているモジュールをPipfileで管理したい

Pythonのモジュール管理や仮装環境構築において、最近[pypa](https://www.pypa.io/en/latest/)に取り込まれたpipenvをPJで使ってみたいと考えました。
最近まで [kennethreitz](https://github.com/kennethreitz)さんのプロジェクトのようでした。

現状、setup.pyやrequirements.txtで管理しているモジュールがあり、環境はvirtualenvとpyenvで管理していることが多いと思います。

Ppienvを導入すると、pyenvやvirtualenvが不要になり、代わりにvenvのみで構築できるようです。


## Pew
Pipenvをインストールすると、依存している[pew](https://github.com/berdario/pew)というモジュールも入る。指定のprojectを使いたい場合は明示的に指定することができる。

[pew](https://github.com/berdario/pew)にあるsetprojectによって、指定した作業Pathの下に`setuptools, pip, wheel` などが入りますが、実行時に、shell環境のPATHの指定をしないと、この[issue](https://github.com/berdario/pew/issues/125)のように、bashが使えなくなることがありました。

ただPipenvでも指定が可能なので、あまり意識せずに今回は使おうと思います。


## 作業ディレクトリの指定
Pipenvはpipenv installした場所に、新しくPipfileとPipfil.lockが作られます。イメージとしてはrubyのgemと一緒で、使用するモジュールを固定にできます。
かつ、pipenv installした場所が仮装環境のルートディレクトリになる動作なので、どこに作りたいかによってchange directoryした方が良いと思います。

特に指定のない場合、 `[現在いるdirectory]/[ランダムに作られるディレクトリ]/の下にインストールモジュールが入ります。また仮装環境をactivateする場所もランダムディレクトリの下になります。

こんな感じ

```
$PATH=/home/saorio/.pyenv/versions/3.6.2/envs/myproject/bin WORKON_HOME=/home/saorio PIPENV_VENV_IN_PROJECT=/home/saorio /home/saorio/.pyenv/versions/3.6.2/envs/myproject/bin/pipenv --python /home/saorio/.pyenv/versions/3.6.2/envs/myproject/bin/python install
```

PATHでpewの入っているパスを指定します。（こうしないとpewが見つからないエラーが出ます)

```
⠋Warning: it looks like pew is not in your PATH. We cannot continue until this is resolved.
```

`--python` は使いたいpythonのバージョンを指定しています。もっと簡単に2系であれば `--two`
とか3系であれば `--three` と指定することもできます。

```
Creating a virtualenv for this project…
Using /home/saorio/.pyenv/versions/3.6.2/envs/myproject/bin/python to create virtualenv…
⠋Already using interpreter /home/saorio/.pyenv/versions/3.6.2/envs/myproject/bin/python
Using base prefix '/home/saorio/.pyenv/versions/3.6.2'
New python executable in /home/saorio/deploy-rtUc-u1X/bin/python
Installing setuptools, pip, wheel...done.

Virtualenv location: /home/saorio/deploy-rtUc-u1X
Installing dependencies from Pipfile.lock (625834)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project's virtualenv, run the following:
 $ pipenv shell
```

もしランダムが嫌な場合は、 `PIPENV_VENV_IN_PROJECT`という指定ができます。
こちらを指定すると、 作業ディレクトリの下に `.venv` のディレクトリが作られ、こちらの下に仮装環境とモジュールが入ります。

Pipenvで作業ディレクトリの指定を明示的にしたい場合は、用意されている以下の環境変数をpipenv install前に指定することでできます。(指定してかつcdする方が確実）

```
WORKON_HOME=/home/saorio
PIPENV_VENV_IN_PROJECT=/home/saorio
```

`PIPENV_IGNORE_VIRTUALENVS` を使うと現在のvirtualenvが無効になるので、こちらはあまり使うことがないかもしれません。



## 環境変数
上記以外にもこちらの記載に指定できる[環境変数](http://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#configuration-with-environment-variables)があります。
また、documentにはありませんが、[こちら](https://github.com/pypa/pipenv/blob/master/pipenv/environments.py)にも環境変数として使える値のようなので、欲しい場合は設定すると良いかもしれません。


| 環境変数          　|設定内容　 　　　　　　　　　|  
|:-----------------|------------------:|
| PIPENV_MAX_ROUNDS |piptoolでの解決の巡回をどれくらいまでするか。デフォルト16回。|   
| PIPENV_PIPFILE    |pipfileの場所を指定 |    
| PIPENV_DONT_LOAD_ENV |.envファイルをロードしないようにする。 |       
| PIPENV_YES | 全てのプロンプトに対し、はいで答える。 |     
|PIPENV_MAX_SUBPROCESS |インストールの時にどれくらいのサブプロセスを使うか。デフォルト16。 |     
| PIPENV_VIRTUALENV |      仮装環境のpipを使う |    
|PIPENV_USE_SYSTEM  |     仮装環境のpipを使う|
|PIPENV_USE_HASHES| ハッシュモードを使う|
|PIPENV_SKIP_VALIDATION|チェックをスキップする(インターネットが遅い環境の場合）|
|PIPENV_DOTENV_LOCATION|.envの環境の指定|
|PIPENV_INSTALL_TIMEOUT|インストールのタイムアウト。デフォルトは15分待つ|
|PIPENV_DONT_USE_PYENV|pyenvを使用しない|
|PYENV_ROOT|pyenvのrootの指定。ない時は~/.pyenvが使われる|
|PYENV_INSTALLED|PYENV_SHELLの値とPYENV_ROOTの値を取得。|
|SESSION_IS_INTERACTIVE|標準出力がttyに接続してるかどうかの評価|
|PIP_ENVSHELL|SHELLの値かPIPENV_SHELLの指定があればそれを使う|
|PIPENV_CACHE_DIR|pipenvのキャッシュディレクトリ|


## よく使うコマンド
`pipenv graph` pip listと一緒でインストールした内容が確認できます。依存関係がわかる出力!
`pipenv check` はセキュリティの脆弱性をチェックしてくれます。

CIでもきちんと動作するかどうか[怪しい点](https://github.com/pypa/pipenv/issues/773)もあり、
まだまだ安定しているとはいえないような点もいくつかありますが、積極的に使っていきたいと思います。