なぜvenvなどのPythonの仮想環境が必要なのか?

2019年6月23日

Pythonは2019年現在で一番人気のあるプログラミング言語の1つです。開発も活発に行われ、2008年にVer3がリリースされましたが、Ver2と互換性がないことがしばしば問題になります。

PythonにはVer2ーVer3の問題のため、複数のバージョンを扱えるvenvやpyenvなどの仮想環境設定ソフトがありますが、私は今までこれらの必要性がいまいち分かりませんでした。

しかし、PythonがLinuxのパッケージ管理に使われていることが原因でvenvを使わないと開発ができない事態に出会ったのでその経過をブログにしておきます。

私がこの問題にハマったときにはちょうど良い資料が見つからなかったので、同じ目にあっている人のために残すものです。

自分の環境について

私がvenvを導入する前のPython実行環境は次のような感じです。

  • OS Debian 8
  • HW Alpharacks VPS ほとんどSSHのターミナルから実行
  • 開発はColaboratoryでやって検証をVPSでやりたかった
  • venvなどの環境仮想化の導入はしていなかった。SystemのPythonやPIPを使って環境を作っていた。
  • numpyやpandasはapt-getでインストールしていた

自分の陥った問題

もともとoanda FXでFX取引のAPIを使ってシステムトレードがしたかったです。なのでColaboratoryでAPIを使ったPythonのプログラムを作りました。

これをVPSサーバにコピーして実行しましたが移動平均を計算しているpandas.dataframe.rolling()が動作しませんでした。エラーから確認すると使っているpandasのバージョンが古くて単にrolling()が実装されていないだけでした。

ではpandasのアップグレードをすればいいんだね。ということでpip3 install -upgrade pandasのようにしてアップグレードを試しましたが以下のエラーが出ます。

ERROR: Complete output from command /usr/bin/python3 /usr/local/lib/python3.4/dist-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /tmp/tmpr4sz6i_d:
ERROR: Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/pip/_vendor/pep517/_in_process.py", line 207, in
main()
(途中略)
File "/usr/local/lib/python3.4/dist-packages/pip/_vendor/pep517/_in_process.py", line 39, in _build_backend
obj = getattr(obj, path_part)
AttributeError: 'module' object has no attribute 'legacy'

ERROR: Command "/usr/bin/python3 /usr/local/lib/python3.4/dist-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /tmp/tmpr4sz6i_d" failed with error code 1 in /tmp/pip-install-nn53f2of/pandas

このエラーはググっても特に出てきませんが、その前に「python 3.4は2019年3月にサポート期間が終了するから新しいPythonを使ってね。」と警告が出ましたので、多分これが原因(実施時は2019年4月)だと思い、Pythonのアップグレードに取り掛かります。以下はその警告。

DEPRECATION: Python 3.4 support has been deprecated. pip 19.1 will be the last one supporting it. Please upgrade your Python as Python 3.4 won't be maintained after March 2019 (cf PEP 429).

Pythonのアップグレードを調べていると、困ったことにDebianのパッケージマネージャでPythonを使っているような雰囲気でした。そして勝手にUpgradeするなと各WEBサイトにも記載されていました。

じゃあDebian自体をUpgradeするしか無いかと思ったらVPSで使えるDebianのバージョンが8までで、最新の9が使えませんでした。(dist-upgradeもできるけどとりあえず除外した)

えー?じゃあ、AlphaRacksを使っている人はOandaFXのAPIを使えないってこと?と思って、ここでやっとOSデフォルトのPythonを開発に使うことに対しての違和感を感じました。

この後調べてみると通常Python開発ではOS使用のPythonは使わない、使ってはいけないなどの情報を見つけ、やっとpyenvやvenvなどの実行環境仮想化の意味が分かったのです。

実行環境仮想化の意味とは

このようにPythonは多くのLinuxにデフォルトでインストールされるようになりましたが、このPythonをプログラムの開発に使っては行けません。なぜなら次のような問題があります。

  • OSデフォルトのPythonはパッケージ管理などで使っているのでユーザーの都合で変更できない。
  • OSデフォルトのPythonは古いバージョンを使っている場合が多く、開発に使うとトラブルのもと。
  • OSデフォルトのPythonの場合、numpyやpandasをapt-getで追加できて便利に見えるが、これもバージョンが古い。
  • 開発案件が複数で、複数バージョンのPythonを利用したい人には対応できない。
  • むりやりOSのPythonをアップデートしようとしたらAptが動かなくなって結局OSを入れ直した。

venvやpyenvはOSで使っているPythonとはべつのPythonを仮想環境にインスールして自分のプログラムを実行するときだけこのPythonを使うことができます。ですので最新のPythonでも古いPythonでも使うことができます。これが現在のPython開発の主流です。

仮想環境の構築

仮想環境の構築は非常に簡単でした。Python3.3より新しいバージョンであれば仮想化のvenvがすでにインストールされているはずです。これから先はvenvを使うことを想定して書きます。次ぎはoadndaenvという仮想環境を作るためのコマンドです。

$ python3 -m venv oandaenv

これで仮想環境が構築されます。注意が必要ですが、上記コマンドでカレントディレクトリに実行ファイルのディレクトリが作られます。この環境下でもろもろ実行するにはactivateを行います。

$ source ./oandaenv/bin/activate

上記の実行でプロンプトに(oandaenv)がつくと思います。このとき実行したコマンドやインストールは仮想環境の中の命令になります。仮想環境を抜けるにはディアクティベートします。

(oandaenv)$ deactivate

作った仮想環境を削除したい場合はフォルダごと削除すればOKです。

$ rm -rf oandaenv

仮想環境内でのインストール、アップグレード

仮想環境化で必要なパッケージをインストールします。私の場合はPythonが3.4だったので3.6にします。Python.orgのWEBサイトから3.6のtgzファイルをダウンロードします。

$ wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz

2019年4月はpython3.7がリリースされていましたが、debian8にはOpenSSLのバージョン依存があって3.7がインストールできなかったので3.6を使います。

(oandaenv)$ tar xzvf Python-3.6.8.tgz
(oandaenv)$ cd Python-3.6.8
(oandaenv)$ ./configure --prefix=/(インストールした場所)/oandaenv
(oandaenv)$ make
(oandaenv)$ make install

上記の命令でPython3.6がインストールできます。私の場合はsetuptoolsとpipが自動でインストールされました。

次にPandasのインストール。

(oandaenv)$ pip install pandas

Pandasもインストールできました。これで長かったPandasインストールできない問題が解決した・・・。

仮想環境内でのプログラムの設置

仮想環境内でプログラムができたら最終的にどこかのサーバーに設置してcronなりWEBサービスとつなげてプログラムを動かすと思います。仮想環境内で作ったプログラムを実行するにはどうすればよいか説明します。

いくつかの情報を検索するとシェルスクリプトの中に$source /〇〇/activateと書く説明が見つかりますが、私の環境では実行できませんでした。

動かなかった理由はわかりませんが、sourceコマンドは実際は別のコマンドのaliasでユーザーの環境変数を読み込まないと動きません。これが多分原因です。

このようなユーザーアカウントに依存した設定はあまり良くありません。自分のアカウント以外では動かない可能性があります。

私の場合はvenv環境下で作ったpyファイルを実行する時にpython3のパスをフルパスで書くようにしたら実行できました。

#!/bin/bash
/home/仮想環境をインストールした場所/bin/python3.6 /home/〇〇/test.py

このようにpython3.6をフルパスで書いたら実行できました。

後は上記ファイルにmain.shなど名前をつけてcronなどと紐づけて自動で実行できるようにすればOKです。

まとめ

この記事ではPythonの仮想環境の意味と実行の方法を書きました。Pythonは外部ライブラリーが豊富なことが魅力ですが、外部ライブラリーを使うのであればPythonのバージョン管理は必要で、環境仮想化も必要な気がします。

プログラムの学習から、実装になる際には必要になる技術(考え方?)だと思いますので参考にしてください。