• 4/30 公開
  • 5/1 増補改訂: 大幅加筆しました。

この記事では、2018年以降に実現可能になったモダンなPythonプロジェクトのはじめかたを整理します。

PythonにもPipenvという公式推奨の高機能なパッケージマネージャーが登場し、さらに2018年に入ってからの機能向上で、npmやyarnのような開発体験が得られるようになってきました。

私はここしばらくはフロントエンドやNode.jsに携わっていて、npmやyarnに慣れきっていたせいか、pipenv導入以前はvirtualenvやpipを組み合わせた開発が面倒で仕方なかったですが、Pipenv導入によって一変しました。

これからはPythonのプロジェクトがよりクリーンかつ簡単に始められるようになり、Developer Experienceも向上するでしょう。

それでは、まずはPythonのインストールからです。

Pythonのインストール

Pythonのインストール方法は様々ですが、Pipenvではpyenvを推奨しています。PipenvとPyenvを組み合わせると、ライブラリだけでなくPython本体のインストールも自動化できます。

次のフローチャートも参考にして、Pyenvが不要な人は別の方法でPythonをインストールしてください。

参考: pyenvが必要かどうかフローチャート

Pyenvのインストール

brew install pyenv

.zshrc.bashrcにpyenvの設定を追加します。

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

PyenvでのPythonのインストール

3.6.5をインストールして標準にする例です。

pyenv install 3.6.5
pyenv global 3.6.5

これで簡単に任意のPythonをいつでも使えるようになりました。

さて、ここからが本題です。

Pipenv: パッケージと仮想環境の管理

pipenvの登場で、PythonでもNode.jsのyarnやnpmのように、プロジェクトを管理できるようになりました。

もはやパッケージ管理にpip freezerequirements.txtを使う必要はありません。面倒だったvirtualenvも意識しないで済むようになりました。

Pipenvのインストール

brew install pipenv

pip経由でもインストールできます。

pip install pipenv

pipenv install: パッケージのインストール

プロジェクトのディレクトリを新たに作成して移動します。

mkdir my_project && cd my_project

アプリで必要なパッケージをインストールします。

例:requestsを使う場合

pipenv install requests

これによって、PipfilePipfile.lockいうファイルがプロジェクト直下に作られて、依存関係が管理されます。

パッケージのバージョンPythonのバージョンを指定することもできます。

パッケージのバージョン指定

pipenv install パッケージ名==バージョン番号

Pythonのバージョン指定

pipenv --python バージョン番号(ex. 3, 3.6, 3.6.5)

Pyenvが設定済みであれば、ここで指定したPythonが自動でインストールされます。

Pipfile scriptsによるアプリに対する操作の抽象化

npmでは、npm run コマンド名によって、どのプロジェクトでも一様に、アプリの起動/静的解析/テスト/コードフォーマットなどを実行できるよう抽象化します。

Pythonでも、pipenvのscripts機能によって、これが自然にできるようになりました。

アプリの起動/起動スクリプト:

プロジェクトごとに、アプリの起動方法は異なると思いますが、毎回打ち込むのは面倒ですよね。

というわけで、pipenv run start一発でアプリを起動できるようにします。

そのためには、プロジェクトのディレクトリ直下のPipfile[scripts]を追加します。

追加したら実行したいコマンドを定義します。

次の例は、pipenv run startapp.pyを起動するものです。

[scripts]
start = "python app.py"

package.jsonscriptsにコマンドを書くのと一緒ですね。

アプリの起動

それでは、実際にアプリを起動してみます。

pipenv run start

どのプロジェクトでもこのコマンドだけで、アプリを起動できるので楽ですね。

Flake8: 静的解析

静的解析もコマンド化します。

ここでは、pyflakeでPEP8とPyFlakeに従って静的解析します。

同じようなにPipfileにコマンドを追加します。

インストール

開発環境だけで使うパッケージをインストールする時は--devオプションをつけます。

pipenv install --dev flake8

Pipfile編集

先ほどと同様にPipfileを編集します。lintオプションで静的解析できる様にします。

[scripts]
 :
lint = "flake8 ."
 :

静的解析実行

静的解析を実行します。lintコマンドで静的解析の実行を抽象化することができました。

pipenv run lint

Autopep8: コードフォーマット

コードフォーマットもscripts化しておきます。autopep8でPEP8に従ってコードを自動修正する例です。

インストール

pipenv install --dev autopep8

Pipfile編集

[scripts]
 :
fix = "autopep8 -ivr ."
 :

オプションのiは上書き、vはデバッグ、rは再帰実行です。

コードフォーマット実行

pipenv run fix

コードフォーマットのコマンドを毎回覚えなくて済みます。

作成したプロジェクトを別の環境で使う

1コマンドで同じプロジェクトを再現できます。

Production環境の場合

pipenv install

依存ライブラリが自動でインストールされます。

Pyenvを使っている場合は、さらにPipfileに定義されたバージョンPythonも同時にインストールしてくれます。GitHubに公開する場合にも便利ですね。

開発環境の場合

pipenv install --dev

開発用のライブラリもインストールされます。

依存ライブラリのセキュリティ脆弱性検出

アプリの依存ライブラリにセキュリティ脆弱性がないかチェックしてくれます。

pipenv check

結果

Checking PEP 508 requirements…
Passed!
Checking installed package safety…
All good!

セキュリティ脆弱性の検出にはsafetyを使っていますが、pipenvに組み込まれているのでインストールする必要はありません。

シェルでのコマンド補間

bashやzshの場合は.bashrc.zshrcなどに以下を追加します。

eval "$(pipenv --completion)"

まとめ

PipenvによってPythonのプロジェクトを簡単に扱えるようになりました。

  • パッケージ管理を一元化できる様になった。
  • アプリの起動、テスト、静的解析などのコマンドも抽象化できるようになった。
  • 普段は仮想環境を意識しなくてよい。
  • 依存ライブラリのセキュリティ脆弱性の検証もできる。
  • pyenvがあればPipfileからライブラリだけでなくPythonのインストールまで自動化できる。

Todo

  • huskeyのようなgit commit時の静的解析やgit push時のテスト
  • ファイルの変更を検知した自動再起動や実行
  • テスト: toxやTravis-CIでのCI

数時間でまとめた内容なので適宜アップデートする予定です。