らくがきちょう

なんとなく ~所属組織/団体とは無関係であり、個人の見解です~

python-lambda-local と lambda-uploader を使ってローカル環境で Lambda 開発を行う

AWSLambda で開発を行う際、Web 管理コンソール上で開発 / デバッグするのは大変です。 python-lambda-local を使うとローカル環境で Lambda を実行出来、更に lambda-uploader を使うとローカル環境から簡単に Lambda へ関数をアップロードすることが出来ます。 Python の外部ライブラリを使う場合、外部ライブラリを含めた .zip ファイルを作成して Web 管理コンソールからアップロードする必要がありますが、lambda-uploader を使えば .zip ファイルを作成することなく、必要なライブラリもアップロードしてくれます。 今回は python-lambda-locallambda-uploader の使い方をメモしておきます。

インストールする

pip でインストールします。

pip install python-lambda-local lambda-uploader

ディレクトリ構造

基本的には以下のようなディレクトリ構成をとります。

my_first_lambda/
├── event.json
├── lambda.json
├── lambda_function.py
└── requirements.txt

ファイルは各々以下の意味を持ちます。

No. ファイル名 説明
1 event.json python-lambda-local で Lambda 関数を実行する際、ハンドラへ渡すイベントの内容を定義する
2 lambda.json lambda-uploader が Lambda へ関数をアップロードする際のパラメータを定義する
3 lambda_function.py python-lambda-local で実行する Lambda 関数の本体 (ファイル名は任意で良い)
4 requirements.txt lambda-uploader が Lambda へ関数をアップロードする際、同梱する外部ライブラリを定義する

python-lambda-local でローカル実行を試す

必要なファイルを用意しながら作業していきます。

requirements.txt

lambda-uploaderrequirements.txt に書かれている外部ライブラリを一緒に .zip して Lambda へアップロードしてくれるようです。 その為、requirements.txt を用意しておきます。 後で用意する Python スクリプトでは requests モジュールを使っているので、ここでは requirements.txtrequests を定義します。

requests

外部モジュールをインストールしておきます。

pip install -r requirements.txt

event.json

Lambda 関数が実行される際、ハンドラへ渡すイベントの内容を定義します。 後で用意する Python サンプルスクリプトはイベントを利用しないものにしたので、ここでは定義自体は無い .json ファイルにしました。

{}

lambda_function.py

Lambda 関数の本体です。 今回は以下のようなコードを用意しました。 サンプルなので例外処理などは未実装です。

import requests
import json

def lambda_handler(event, context):
    response = requests.get('http://ifconfig.cc')
    return {
        'statusCode': 200,
        'body': json.dumps(response.text)
    }

この時点で用意した Lambda 関数をローカル環境で実行してみます。 python-lambda-local の構文は以下の通りです。

python-lambda-local -f [HANDLER_NAME] [PYTHON_FILE] [EVENT_FILE]

今回の場合は以下のように指定します。

python-lambda-local -f lambda_handler lambda_function.py event.json

実際の実行例は以下の通りです。

# python-lambda-local -f lambda_handler lambda_function.py event.json
[root - INFO - 2020-02-01 19:12:04,868] Event: {}
[root - INFO - 2020-02-01 19:12:04,868] START RequestId: f4891f8b-f6dd-4398-a45e-821c7c37c516 Version:
[root - INFO - 2020-02-01 19:12:05,362] END RequestId: f4891f8b-f6dd-4398-a45e-821c7c37c516
[root - INFO - 2020-02-01 19:12:05,363] REPORT RequestId: f4891f8b-f6dd-4398-a45e-821c7c37c516  Duration: 309.38 ms
[root - INFO - 2020-02-01 19:12:05,363] RESULT:
{'statusCode': 200, 'body': '"XXX.XXX.XXX.XXX"'}

lambda.json

lambda-uploader でアップロードする Lambda 関数のパラメータを定義します。 Role の ARN は Web 管理コンソールから確認しますが、既存の Lambda 関数があれば aws lambda list-functionsaws lambda get-function --function-name [FUNCTION] を使って既存 Lambda 関数の情報を参考にすることも出来ます。 あと、runtime は必須ではありませんが、省略すると python2.7 が指定されてしまうようだったので、ここでは明示的に python3.8 を指定しています。

{
  "name": "my_first_lambda",
  "description": "my_first_lambda description.",
  "region": "ap-northeast-1",
  "runtime": "python3.8",
  "handler": "lambda_function.lambda_handler",
  "role": "arn:aws:iam::123456789012:role/LambdaSample",
  "timeout": 30,
  "memory": 128
}

用意が出来たら Lambda 関数をアップロードします。

lambda-uploader

実行例は以下の通りです。

# lambda-uploader
λ Building Package
λ Uploading Package
λ Fin

これで Lambda 関数がアップロードされたはずです。