AWS LambdaがPython3.6に対応したのでpyenvとpyenv-virtualenvで環境構築してみた

アイキャッチ

こんにちは、臼田です。

LambdaがPython3.6に対応しました!

https://aws.amazon.com/jp/about-aws/whats-new/2017/04/aws-lambda-supports-python-3-6/

というわけで使ってみたいのですが、私の環境はmacデフォルトのPython2.7なので、Pythonの複数バージョンを切り替えて使えるpyenvと、それをより使いやすくするpyenv-virtualenvを入れて環境構築したいと思います。

pyenvとpyenv-virtualenvとは

pyenv

pyenvは、Pythonの複数バージョンを管理して同時に利用するためのツールです。

https://github.com/pyenv/pyenv

特に、Pythonでは2.7系と3.x系のどちらも利用することがあり、派閥争いが激しい状況なので複数のバージョンを利用できることが重要です。

pyenvではglobalで利用するバージョンを切り替えたり、一部のフォルダだけ別のバージョンにしたり出来ます。

pyenv-virtualenv

pyenv-virtualenvは、pyenvのプラグインです。

https://github.com/pyenv/pyenv-virtualenv

pyenvと同じ作者で、同じような名前のvertualenvとは無関係のようです(ここ誤解しやすい)。

pyenvだけだと、バージョン毎に環境が別れますが、pyenv-virtualenvを利用すれば、

同一バージョンの別環境を名前付きで作成することが出来ます。

pipなどでプラグインをインストールすると思いますが、「Pythonのバージョンは同じだけどプラグインのバージョンは違う」みたいな環境も作れちゃうということですね。

 

ちなみに、今回は下記サイトを参考にさせていただきました。

pyenvとvirtualenvとpyenv-virtualenv

環境構築

環境

環境構築前の状態は以下のとおりです。

$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.4
BuildVersion: 16E195
$ brew --version
Homebrew 1.1.12
Homebrew/homebrew-core (git revision 900a5; last commit 2017-04-06)
$ python --version
Python 2.7.10
$ pip --version
pip 9.0.1 from /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7)

pyenvインストール

macであればHomebrewで簡単にインストールできます。

$ brew install pyenv

PATHを通したりする設定をbash_profileに追記して再読込みします。

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

インストールできたのでpyenvを確認してみます。

$ pyenv --version
pyenv 1.0.10
$ pyenv versions
* system (set by /Users/usuda.keisuke/.pyenv/version)

versionsサブコマンドは現在pyenvにインストールされているバージョンの一覧を表示しますが、pyenvをインストールしたばかりなので、system(macのデフォルト)しかありません。

ちなみに、サブコマンドをhelpで確認すると以下のようになっています。

$ pyenv help
Usage: pyenv <command> [<args>]

Some useful pyenv commands are:
   commands    List all available pyenv commands
   local       Set or show the local application-specific Python version
   global      Set or show the global Python version
   shell       Set or show the shell-specific Python version
   install     Install a Python version using python-build
   uninstall   Uninstall a specific Python version
   rehash      Rehash pyenv shims (run this after installing executables)
   version     Show the current Python version and its origin
   versions    List all Python versions available to pyenv
   which       Display the full path to an executable
   whence      List all Python versions that contain the given executable

新しいバージョンを追加するときはinstallで、バージョンを変更するのが主にgloballocalです。

実際に使ってみましょう。

pyenvでPython3.6のインストール

まずは、pyenvで利用できるバージョンを確認します。

$ pyenv install --list
Available versions:
2.1.3
2.2.3
…省略…
2.7.10
2.7.11
2.7.12
2.7.13
…省略…
3.6.0
3.6-dev
3.6.1
3.7-dev
anaconda-1.4.0
…省略…

省略をしましたが、すごく沢山のバージョンが利用できます。

$ pyenv install --list | wc -l
301

通常のPythonのバージョンもあれば、Anacondaやminicondaといったディストリビューションや別実装のjython,PyPy等も含まれています。

さて、今回はLambdaで利用するPython3.6と同じ環境を作成したいので、先にLambdaでバージョン確認すると以下のようになりました。

import sys

def lambda_handler(event, context):
print(sys.version_info)
sys.version_info(major=3, minor=6, micro=1, releaselevel='final', serial=0)

というわけで、3.6.1をインストールします。

$ pyenv install 3.6.1
Downloading Python-3.6.1.tar.xz...
-> https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz
Installing Python-3.6.1...
Installed Python-3.6.1 to /Users/usuda.keisuke/.pyenv/versions/3.6.1

$ pyenv versions
* system (set by /Users/usuda.keisuke/.pyenv/version)
  3.6.1

インストールできたのでバージョンを切り替えてみます。

$ pyenv global 3.6.1
$ pyenv versions
  system
* 3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)
$ pyenv version
3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)

pyenv versionsであれば*がカレントのバージョンで、pyenv versionであればカレントのバージョンのみ表示となります。

Python3.6の動作確認

さて、せっかく切り替わったのでPython3.6でしか利用できない機能を利用して、適切に動作することを確認します。

下記によると、f-stringという機能が追加されているようです。

Python 3.6の概要 (その1 - f文字列)

コンソールからやってみます。

$ python
Python 3.6.1 (default, Apr 19 2017, 14:12:23)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> f'1+1={1+1}'
'1+1=2'

ちゃんと処理されました。

ちなみに、バージョンを戻してみると動きません。

$ pyenv global system
$ pyenv versions
* system (set by /Users/usuda.keisuke/.pyenv/version)
  3.6.1
$ python
Python 2.7.10 (default, Feb  6 2017, 23:53:20)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> f'1+1={1+1}'
  File "<stdin>", line 1
    f'1+1={1+1}'
               ^
SyntaxError: invalid syntax

 

pyenv-virtualenvのインストール

さて、pyenvはインストール出来たので、pyenv-virtualenvをインストールします。

同じようにHomebrewでインストール出来ます。

$ brew install pyenv-virtualenv

新しく名前の付いた3.6.1の環境を作成してみます。

pyenv-virtualenvはpyenv virtualenv [バージョン] [仮想環境名]と実行します。

[バージョン]を省略するとカレントバージョンを利用します。

$ pyenv versions
* system (set by /Users/usuda.keisuke/.pyenv/version)
 3.6.1
$ pyenv global 3.6.1
$ pyenv versions
 system
* 3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)
$ pyenv virtualenvs
$ pyenv virtualenv test_3.6.1
$ pyenv virtualenvs
 3.6.1/envs/test_3.6.1 (created from /Users/usuda.keisuke/.pyenv/versions/3.6.1)
 test_3.6.1 (created from /Users/usuda.keisuke/.pyenv/versions/3.6.1)
$ pyenv versions
 system
* 3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)
 3.6.1/envs/test_3.6.1
 test_3.6.1
$ pyenv global test_3.6.1
$ pyenv versions
 system
 3.6.1
 3.6.1/envs/test_3.6.1
* test_3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)

 

test_3.6.1以外に3.6.1/envs/test_3.6.1も出来ているように見えますが、実際はtest_3.6.1が3.6.1/envs/test_3.6.1のシンボリックリンクになっているので1つです。

試しにpipでパッケージを追加してみます。

$ pip list
pip (9.0.1)
setuptools (28.8.0)
$ pip install requests
Collecting requests
 Using cached requests-2.13.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.13.0
$ pip list
pip (9.0.1)
requests (2.13.0)
setuptools (28.8.0)
$ pyenv global 3.6.1
$ pip list
pip (9.0.1)
setuptools (28.8.0)

元の3.6.1には影響せずrequestsをインストール出来ました。

いらなくなった環境は、pyenv uninstall -> y で削除できます。

$ pyenv uninstall test_3.6.1
pyenv-virtualenv: remove /Users/usuda.keisuke/.pyenv/versions/3.6.1/envs/test_3.6.1? y
$ pyenv versions
system
* 3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)

LambdaのPython3.6用のディレクトリ作成

pyenvとpyenv-virtualenvがインストール出来たので、実際にLambdaのPython3.6のための環境を作成します。

まず、任意のLambda Python3.6用のフォルダを作成します。

$ mkdir lambda3
$ cd lambda3/

Lambda Python3.6用のpyenvの環境を作成します。

$ pyenv virtualenv 3.6.1 lambda3

これを作成したディレクトリに適用します。

globalの設定に依存せず、ディレクトリ配下のバージョンを固定するにはpyenv localコマンドを利用します。

$ pyenv local lambda3
$ pyenv versions
system
3.6.1
3.6.1/envs/lambda3
* lambda3 (set by /Users/usuda.keisuke/repo/lambda3/.python-version)

ディレクトリの外では、globalの環境が維持されています。

$ cd ../
$ pyenv versions
system
* 3.6.1 (set by /Users/usuda.keisuke/.pyenv/version)
3.6.1/envs/lambda3
lambda3

これでLambda用のPython3.6の環境が出来ました。

最後に

pyenvとpyenv-virtualenvがあると、複数バージョンの利用と、同一バージョンでもパッケージを使い分けることが出来るので、インターネットからスクリプトを拾ってきても修正せずに利用出来ますしなにかと便利です。

ぜひ環境を構築して、LambdaをPython3.6で使ってみましょう!