Python開発: Pipenvで仮想環境管理とパッケージ管理を一元化

# はじめに
Pythonでプロジェクトを管理する際に欠かせないのが、仮想環境とパッケージ管理です。これらを適切に扱うことで、プロジェクトごとに異なる依存関係を安全に管理できます。

本記事では、Pipenvを使った仮想環境管理とパッケージ管理について、初心者にも分かりやすく解説します。

## Pipenvとは？
`Pipenv`は、Python公式が推奨する仮想環境管理とパッケージ管理を一元化できるツールです。以下のような特徴があります
- 仮想環境の作成と管理を自動化
- 依存関係の明確化とロックファイルの生成
- `Pipfile`によるわかりやすい依存管理
- 環境の再現性を保証

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

## Pipenvのインストール
Pipenvをインストールするには、以下のコマンドを実行します。
```bash
pip install pipenv
```

Homebrewでインストールする場合
```bash
brew install pipenv
```

インストールが完了したら、インストールされていることの確認として`pipenv --version`でバージョンを確認してみましょう。

## Pipenvを使った基本的な操作
### プロジェクトの初期化
新しいプロジェクトでPipenvを初期化するには、以下を実行します。
`pipenv install`コマンドは、`Pipfile`が存在しない場合に新しい`Pipfile`を作成します。
`Pipfile`がすでに存在している場合は、記載された依存関係をインストールします。加えて、`Pipfile.lock`が存在しない場合は、新たに生成されます。
```bash
pipenv install
```

## 生成されるPipfileとPipfile.lockについて説明

### Pipfile
依存パッケージとPythonのバージョンを記述する設定ファイル。
以下は、`Pipfile`のサンプルとその構成要素の説明です。
```toml:Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
requests = "*"
flask = ">=2.0"

[dev-packages]
pytest = "^7.0"
black = "*"

[requires]
python_version = "3.12"
```

| セクション        | 内容                                                   | 例                                      |
|-------------------|--------------------------------------------------------|-----------------------------------------|
| **`[[source]]`**   | パッケージソースを指定する                               | `url = "https://pypi.org/simple"`       |
| **`[requires]`**   | 必要なPythonのバージョンを指定                           | `python_version = "3.12"`              |
| **`[packages]`**   | 本番環境に必要なパッケージを指定                         | `requests = "*"`                       |
| **`[dev-packages]`** | 開発環境に必要なパッケージを指定（例: テスト用パッケージ） | `pytest = "^7.0"`                      |

---

### `Pipfile.lock` の詳細
依存パッケージの正確なバージョンとハッシュを記録するロックファイル。
以下は、`Pipfile`のサンプルとその構成要素の説明です。
```json:Pipfile.lock
{
    "_meta": {
        "hash": {
            "sha256": "abc123...",
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.12"
        }
    },
    "default": {
        "flask": {
            "version": "==2.3.2",
            "hashes": [
                "sha256:abc...",
                "sha256:def..."
            ]
        },
        "requests": {
            "version": "==2.31.0",
            "hashes": [
                "sha256:ghi...",
                "sha256:jkl..."
            ]
        }
    },
    "develop": {
        "pytest": {
            "version": "==7.4.0",
            "hashes": [
                "sha256:mno..."
            ]
        },
        "black": {
            "version": "==23.9b0",
            "hashes": [
                "sha256:pqr..."
            ]
        }
    }
}
```

| セクション       | 内容                                             |
|------------------|--------------------------------------------------|
| **`_meta`**      | ファイルに関するメタ情報（ハッシュ値、Pythonバージョンなど） |
| **`default`**    | 本番環境用パッケージとそのバージョン、ハッシュ情報     |
| **`develop`**    | 開発環境用パッケージとそのバージョン、ハッシュ情報     |

### Pythonのバージョンを指定してプロジェクトの初期化を行う場合
例: Pythonのバージョン3.12で初期化を行う場合
```bash
pipenv --python 3.12
```

ローカル環境に初期化で使用するPythonのバージョンが存在していない場合
```bash
% pipenv --python 3.12 
Warning: Python 3.12 was not found on your system...
Would you like us to install CPython 3.12.7 with Pyenv? [Y/n]: Y
Installing CPython 3.12.7 with /opt/homebrew/bin/pyenv (this may take a few minutes)...
✔ Success! 
```

### パッケージのインストール
パッケージをインストールするには、`pipenv install パッケージ名`を使います。
例：requestsパッケージをインストール
```bash
pipenv install requests
```

バージョン指定してインストールする場合、pipと同じように`>=`, `==`, `<=`などでバージョン指定してインストール可能です。
```bash
pipenv install requests>=1.2
```
インストール後、`Pipfile`に記録され、`Pipfile.lock`が生成・更新されます。

### 開発用パッケージのインストール
開発時にのみ必要なパッケージは以下のようにインストールします：
```bash
pipenv install pytest --dev
```

### パッケージのアンインストール
パッケージをインストールするには、`pipenv uninstall パッケージ名`を使います。
uninstall実行後、PipfileとPipfile.lockが再生成されuninstallしたパッケージが削除されます。
例：requestsパッケージをアンインストール
```bash
pipenv uninstall requests
```

### 仮想環境への有効化
仮想環境に入るには以下を実行します
```bash
pipenv shell
```

仮想環境から抜ける時はexitを実行します
```bash
exit
```

## パッケージの更新
```bash
pipenv update
```

## Pipfile.lockから依存関係をインストール
```bash
pipenv sync
```

## 依存関係のセキュリティ脆弱性をチェック
[PyUp Safety](https://github.com/pyupio/safety)を使用したセキュリティ上の脆弱性を確認し、[PEP508](https://peps.python.org/pep-0508/)(Pythonの依存関係仕様)に準拠しているかチェックします。
```bash
pipenv check
```

## パッケージの依存関係をツリー形式で表示
`pipenv graph`コマンドは、現在の仮想環境にインストールされているすべてのパッケージと、それらの依存関係をツリー形式で表示します。
```bash
% pipenv graph               
Django==5.1.3
├── asgiref 
└── sqlparse 
pandas==2.2.3
├── numpy 
├── python-dateutil 
│   └── six 
├── pytz 
└── tzdata
```

## Pipfile.lockに指定されていないパッケージを仮想環境からアンインストール
```bash
pipenv clean
```

## pipfile.lockから依存関係をファイルへ書き出し
依存関係をファイルへ書き出すには、`pipenv requirements > ファイル名`を使います。
例: requirements.txtへ書き出し
```bash
pipenv requirements > requirements.txt
```
開発用パッケージを含めて書き出す場合は`--dev`をつけることで書き出し可能です。
```bash
pipenv requirements --dev > requirements.txt
```

## Pipenv環境の削除
Pipenvで作成した仮想環境を削除するには以下を実行します。
```bash
pipenv --rm
```
これにより、プロジェクトに紐付いた仮想環境が削除されます。
仮想環境の再作成が必要な場合、`pipenv install`を再実行してください。

## まとめ
Pipenvは、仮想環境とパッケージ管理をシンプルに統合する便利なツールです。特に、初心者がPythonプロジェクトを始める際には使いやすく、PipfileとPipfile.lockを通じてプロジェクトの環境をしっかり管理できます。

ぜひPipenvを使ってPythonプロジェクトを管理してみてください！