Lambda (Python) のローカル環境を整えるため,python-lambda-local を試した.python-lambda-local を使うと,Python コードを Lambda にデプロイすることなく動作確認ができるようになる.Apex を使っていれば apex invoke
でお手軽に実行することもできるけど,やはり Lambda に依存せず,単独で実行したいという要件はある.Lambda のローカル環境は誰に聞いても困っている印象がある.
前提
インストールは pip を実行するだけで良い.また,今回紹介するディレクトリ構成は Apex で Lambda をデプロイする前提にしている.
$ pip install python-lambda-local
BluePrint : hello-world-python
まずは AWS に依存せず,Python ライブラリにも依存せず,単体で実行できるコードとして,BluePrint の hello-world-python を試した.ディレクトリ構成は以下のようになっている.
. ├── event.json ├── functions │ └── myfunc │ └── main.py └── project.json
myfunc/main.py
は以下のようなコードにした.シンプルにイベントを受けて,表示するだけの実装にしている.
import json print('Loading function') def lambda_handler(event, context): print("function = myfunc, value1 = " + event['key1']) print("function = myfunc, value2 = " + event['key2']) print("function = myfunc, value3 = " + event['key3'])
ここで python-lambda-local で実行すると以下のようになる.オプションとしては --function
でハンドラを指定して,-t
でタイムアウトを指定する.あとは Python コードとイベントを指定する.
$ python-lambda-local --function lambda_handler --timeout 5 functions/myfunc/main.py event.json Loading function [root - INFO - 2017-07-30 16:16:36,272] Event: {u'key3': u'value3', u'key2': u'value2', u'key1': u'value1'} [root - INFO - 2017-07-30 16:16:36,273] START RequestId: 9e683e91-821f-4680-b8e2-bcf37c7eb44f function = myfunc, value1 = value1 function = myfunc, value2 = value2 function = myfunc, value3 = value3 [root - INFO - 2017-07-30 16:16:36,273] END RequestId: 9e683e91-821f-4680-b8e2-bcf37c7eb44f [root - INFO - 2017-07-30 16:16:36,274] RESULT: None [root - INFO - 2017-07-30 16:16:36,274] REPORT RequestId: 9e683e91-821f-4680-b8e2-bcf37c7eb44f Duration: 0.38 ms
簡単に動いた!
BluePrint : s3-get-object-python
次は AWS に依存していて,Python ライブラリにも依存するコードとして,BluePrint の s3-get-object-python を試した.ディレクトリ構成は以下のようになっている.
. ├── event.json ├── functions │ └── myfunc │ ├── main.py │ ├── requirements.txt │ └── (ライブラリいろいろ) └── project.json
myfunc/main.py
は以下のようなコードにした.S3 Put のイベントを受けて,Put されたファイルの Content-Type を表示している.なお,S3 Put のイベントは量が多いため,割愛するが,公式ドキュメントにちゃんと載っている.
from __future__ import print_function import json import urllib import boto3 print('Loading function') s3 = boto3.client('s3') def lambda_handler(event, context): # Get the object from the event and show its content type bucket = event['Records'][0]['s3']['bucket']['name'] key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8')) try: response = s3.get_object(Bucket=bucket, Key=key) print("CONTENT TYPE: " + response['ContentType']) return response['ContentType'] except Exception as e: print(e) print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket)) raise e
ここで python-lambda-local で実行すると以下のようになる.
$ python-lambda-local --function lambda_handler --library functions/myfunc --timeout 5 functions/myfunc/main.py event.json [root - INFO - 2017-07-30 23:14:18,203] START RequestId: 07669e19-37af-4640-ae65-859dadd758ed [botocore.vendored.requests.packages.urllib3.connectionpool - INFO - 2017-07-30 23:14:18,214] Starting new HTTPS connection (1): s3-ap-northeast-1.amazonaws.com CONTENT TYPE: text/plain [root - INFO - 2017-07-30 23:14:18,721] END RequestId: 07669e19-37af-4640-ae65-859dadd758ed [root - INFO - 2017-07-30 23:14:18,722] RESULT: text/plain [root - INFO - 2017-07-30 23:14:18,722] REPORT RequestId: 07669e19-37af-4640-ae65-859dadd758ed Duration: 517.71 ms
問題なく動いた!
気を付けるポイント
python-lambda-local を使ってみて,数点気を付けるポイントがあった.
1. /lib
ではなくルートディレクトリにライブラリをインストールする
公式ドキュメントにも書いてある通り,pip で Python ライブラリをインストールする場合,Lambda の場合はルートディレクトリに配置する必要がある.よって,python-lambda-local のドキュメントにあるような /lib
ディレクトリを用意するのではなく,main.py
と同じルートディレクトリにそのままインストールする必要がある.具体的には以下のようなコマンドになる.
$ pip install --requirement functions/myfunc/requirements.txt --target functions/myfunc
2. requirements.txt
に boto3
を明示する必要がある
次も公式ドキュメントに書いてある内容だが,Lambda にはデフォルトで Boto 3 がインストールされているため,わざわざ requirements.txt
に書く必要がないようになっている.ただし,ローカル環境で実行する場合には必要なので,結果的に書く必要があった.今回は以下のファイルを用意した.
urllib boto3
まとめ
- Lambda (Python) のローカル環境を整えるために python-lambda-local を試してみた
- 簡単に使えたし AWS サービスとの接続もできたため一般的なユースケースは網羅できそう
- ライブラリのインストールディレクトリなど少し気を付けるポイントはある
関連記事
Apex を使って複数環境にデプロイする方法は前にまとめてある.Apex ユーザーには参考になる内容だと思う.