てくなべ (tekunabe)

ansible / network / automation / StackStorm

[Python] pyenv と pipenv による python 仮想環境を構築する(CentOS 7 ほぼ初期状態から )


■ はじめに

Python の仮想環境は、いままで virtualenv/venv のみ利用していたのですが 「2018年のPythonプロジェクトのはじめかた」という記事を見て、pyenv や pipenv 試してみようと思いました。

この記事では、準備、仮想環境の作成と復元を試したときの手順を記載します。 (自分向けメモの意味合いが強いため説明が雑で申し訳ないです。)

今回前提とする環境

pyenv / pipenv とは

  • pyenv は 複数のバージョンの Python を管理するツール。
  • pipenv は 複数のバージョンの Python とパッケージのまとめて管理するツール。pyenv とも連携可能。 Pipefile を使うのが特徴。


環境の準備

pip の準備

インストール

公式ドキュメントの Installing with get-pip.py のインストール方法を参考にインストールします。

$ curl https://bootstrap.pypa.io/get-pip.py | sudo python
(...略...)
Successfully installed pip-18.1 setuptools-40.6.3 wheel-0.32.3

確認

$ pip --version
pip 18.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)


pyenv の準備

インストール

pyenv/pyenv リポジトリの READMME.md にある Basic GitHub Checkout のインストール方法を参考にインストールします。

pyenv のインストールには git が必要なため予めインストールします。

$ yum install git
(...略...)

Installed:
  git.x86_64 0:1.8.3.1-20.el7

Dependency Installed:
  perl-Error.noarch 1:0.17020-2.el7        perl-Git.noarch 0:1.8.3.1-20.el7        perl-TermReadKey.x86_64 0:2.30-20.el7

Complete!

ここから pyenv 本編です。

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
$ exec "$SHELL" -l

確認

$ pyenv --version
pyenv 1.2.8
$ pyenv install --list
Available versions:
(...略...)
  3.6.5
  3.6.6
  3.6.7
  3.6.8
  3.7.0
  3.7-dev
  3.7.1
  3.7.2
(...略...)

その他必要なパッケージインストール

$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel

上記は、あとで pipenv --python x.x.x コマンドを実行したときに、

zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1

というエラーに遭遇して、「CentOS7にPython3(Anaconda3)をインストール」という記事で知った対処方法です。 pyenv 公式 Wiki にの FAQ の Suggested build environmentに記載があります。(今回はCentOS/Fedora 21 and belowのケースを選択)


pipenv の準備

インストール

$ sudo pip install pipenv
Collecting pipenv
(...略...)
Successfully installed certifi-2018.11.29 enum34-1.1.6 pipenv-2018.11.26 typing-3.6.6 virtualenv-16.1.0 virtualenv-clone-0.4.0

確認

$ pipenv --version 3.6.7
pipenv, version 2018.11.26

ここまでで基本的な準備は終わります。




■ 仮想環境の作成

準備ができたので、特定の Python のバージョンとパッケージをインストールした仮想環境を作ってみます。

プロジェクトディレクトリの作成

mkdir mypj
cd mypj

使用する Python バージョンの選択

今回は、 3.6.7 を指定します。

$ pipenv --python 3.6.7
Warning: Python 3.6.7 was not found on your system...
Would you like us to install CPython 3.6.7 with pyenv? [Y/n]: y
Error: invalid input
Would you like us to install CPython 3.6.7 with pyenv? [Y/n]:
Installing CPython 3.6.7 with pyenv (this may take a few minutes)...
✔ Success!
Downloading Python-3.6.7.tar.xz...
-> https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz
Installing Python-3.6.7...
Installed Python-3.6.7 to /home/vagrant/.pyenv/versions/3.6.7


Creating a virtualenv for this project...
Pipfile: /home/vagrant/Pipfile
Using /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6 (3.6.7) to create virtualenv...
⠸ Creating virtual environment...Using base prefix '/home/vagrant/.pyenv/versions/3.6.7'
New python executable in /home/vagrant/.local/share/virtualenvs/vagrant-G6U0N2py/bin/python3.6
Also creating executable in /home/vagrant/.local/share/virtualenvs/vagrant-G6U0N2py/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6

✔ Successfully created virtual environment!
Virtualenv location: /home/vagrant/.local/share/virtualenvs/vagrant-G6U0N2py
Creating a Pipfile for this project...

このときに Pipfile というファイルが作成されます。

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.6"

python_version = "3.6" という指定なので、細かいバージョンの指定にはなっていません。別途、python_full_version = "3.6.7" のような指定方法もあるようです。

パッケージの追加

ここでは、netmiko というネットワーク機器を操作するパッケージをインストールしてみます。

$ pipenv install netmiko
Creating a virtualenv for this project...
Pipfile: /home/vagrant/mypj/Pipfile
Using /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6 (3.6.7) to create virtualenv...
⠧ Creating virtual environment...Using base prefix '/home/vagrant/.pyenv/versions/3.6.7'
New python executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python3.6
Also creating executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6

✔ Successfully created virtual environment!
Virtualenv location: /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX
Installing netmiko...
Adding netmiko to Pipfile's [packages]...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
✔ Success!
Updated Pipfile.lock (153fc2)!
Installing dependencies from Pipfile.lock (153fc2)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 15/15 — 00:00:07
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$

Pipfile[packages]netmiko が追加されます。(抜粋)

[packages]
netmiko = "*"

また、 Pipfile.lock というファイルが作成されます。

{
    "_meta": {
        "hash": {
            "sha256": "57158d2b8971d66a6434756fc9620915aa380f83e94ff9871202f22643153fc2"
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.6"
        },
        "sources": [
(...略...)

作成された仮想環境に入る

先ほどと同じく、Pipfile たちがあるディレクトリで、 pipenv shell コマンドを実行すると、仮想環境に入れます。

$ pipenv shell
Launching subshell in virtual environment...
$  . /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/activate
(mypj) $
(mypj) $ python --version
Python 3.6.7
(mypj) $ pip list | grep netmiko
netmiko      2.3.0

指定したとおり、 Python 3.6.7 の環境で、netmiko がインストールされていることが確認できました。

仮想環境から抜けるために deactivate コマンドを実行します。

(mypj) $ deactivate




■ 別マシンで仮想環境の復元

先程作成された、 Pipifile と、Pipfile.lock ファイルを理想して、別マシンで仮想環境(今回は Python 3.6.7 と netmiko)を復元してみます。 pip、pyenv、pipenv は、別マシンでも準備済みとします。

プロジェクトディレクトリの作成

$ mkdir mypj
$ cd mypj

Pipfile のコピー

何かしらの方法で、Pipifile と、Pipfile.lock をコピーしてきます。

仮想環境の復元

pipenv sync コマンドで復元します。

$ pipenv sync
Warning: Python 3.6 was not found on your system...
Would you like us to install CPython 3.6.8 with pyenv? [Y/n]: y
Error: invalid input
Would you like us to install CPython 3.6.8 with pyenv? [Y/n]:
Installing CPython 3.6.8 with pyenv (this may take a few minutes)...
✔ Success!
Downloading Python-3.6.8.tar.xz...
-> https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz
Installing Python-3.6.8...
Installed Python-3.6.8 to /home/vagrant/.pyenv/versions/3.6.8


Creating a virtualenv for this project...
Pipfile: /home/vagrant/mypj/Pipfile
Using /home/vagrant/.pyenv/versions/3.6.8/bin/python3 (3.6.8) to create virtualenv...
⠋ Creating virtual environment...Using base prefix '/home/vagrant/.pyenv/versions/3.6.8'
New python executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python3
Also creating executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/vagrant/.pyenv/versions/3.6.8/bin/python3

✔ Successfully created virtual environment!
Virtualenv location: /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX
Installing dependencies from Pipfile.lock (153fc2)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 15/15 — 00:00:20
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
All dependencies are now up-to-date!

Pipfile 内での Python バージョンの指定が python_version = "3.6" だったためか、仮想環境作成時の 3.6.7 ではななく、 3.6.8 がインストールされました。

続いて、復元された仮想環境に入って、Python のバージョンと netmiko が入っていいることを確認します。

(mypj) $ python --version
Python 3.6.8
(mypj) $ pip list | grep netmiko
netmiko      2.3.0
(mypj) $ deactivate


■ まとめ

pyenv、pipenv を利用して、Python のバージョンと利用するパッケージをまとめ管理する仮想環境の定義ができました。 仮想環境の分け方はこの他にも、virtualevn/venv でのみで分ける、VMごと分ける、コンテナごと分けるなどの方法もありますが、必要に応じて使い分けができればと思います。

(おまけ)コピペ用

「環境の準備」の一連のコマンドをコピペだけで実行できるようにしたものです。

# pip
curl https://bootstrap.pypa.io/get-pip.py | sudo python

# git
sudo yum -y install git

# pyenv
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
exec "$SHELL" -l
sudo yum -y install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel

# pipenv
sudo pip install pipenv

参考

qiita.com

qiita.com

msh5.hatenablog.jp