Python
AWS
Python3
lambda
APIGateway

【API Gateway】AWS Lambda統合のPythonでHello, world

Amazon API GatewayからPythonで書いたAWS Lambdaを起動してみたい、と思ってやってみました。
公式ドキュメント では、Pythonのコード例がなかったので、備忘録的に書いてみます。

手順

AWS Lambda関数の作成

  1. AWSコンソールにサインインして、[サービス]→[AWS Lambda]を選択。
  2. 関数一覧画面が表示されるので、右上の「関数の作成」ボタンをクリック。
    image.png

  3. 「一から作成」を選択し、以下のように入力

    • 名前:hello-world-python
    • ランタイム:Python 3.6
    • ロール:テンプレートから新しいロールを作成
    • ロール名:hello-world-python-role
    • ポリシーテンプレート:テストハーネスのアクセス権限 image.png
  4. 入力したら「関数の作成」ボタンをクリック。 すると、以下のような関数のデザイン画面に切り替わります。
    image.png

AWS Lambda関数のトリガーを設定

この状態では、作成したAWS Lambda関数を実行するきっかけとなるトリガーがありません。

今回はAPI Gatewayから呼び出したいので、Designerパネルの「トリガーの追加」の下の「API Gateway」をクリックします。

すると、「トリガーの設定」という項目がDesignerパネルの下に現れるので、以下のように設定します。

  • API:新規APIの作成
  • API名:LambdaHelloPython
  • デプロイされるステージ:dev
  • セキュリティ:オープン image.png

入力できたら「追加」ボタンをクリックします。すると、下図のようにDesignerパネルの「API Gateway」の項目のところに「保存されていない変更」と表示されるので、一度画面右上の保存ボタンをクリックして保存しておきます。
image.png

AWS Lambda関数の実装

次に、PythonでAWS Lambda関数を記述します。
Designerパネルの「hello-world-python」の部分をクリックすると、Desingerパネルの下に「関数コード」パネルが表示さます。ここが簡易的なエディタになっており、直接コードを記述できます。

ここで、初期状態で入力されているコードは以下のようになっています。

def lambda_handler(event, context):
    # TODO implement
    return 'Hello from AWS Lambda'

このままだとAPI Gatewayが期待する戻り値と一致しないので、戻り値を以下のように修正します。

def lambda_handler(event, context):
    return {
        'isBase64Encoded': False,
        'statusCode': 200,
        'headers': {},
        'body': '{"message": "Hello from AWS Lambda"}'
    }

API GatewayからAWS Lambda関数を呼び出した場合、そのAWS Lambda関数は上記コード例のように、以下の4つの項目を返す必要があります(プロキシ統合のためのAWS Lambda関数の出力形式より)。

  • isBase64Encoded: TrueまたはFalsebodyがバイナリの場合、Base64エンコード文字列でbodyに記述の上、この項目をTrueとします。
  • statusCode: HTTPレスポンスのステータスコードを整数型で記述します。
  • headers: HTTPレスポンスのヘッダーに記述したいものがあれば、ディクショナリでここに記述します。
  • body: HTTPレスポンスのボディを文字列で記述します。

AWS Lambda関数のコードを変更したら画面右上の「保存」をクリックします。

AWS Lambda関数のテスト

保存したAWS Lambda関数のコードに間違いがないかどうか、テストしましょう。「保存」ボタンのすぐ左の「テスト」ボタンをクリックします。  
すると、「テストイベントの設定」という画面が開きますので、以下のように設定します。

  • 「新しいテストイベントの作成」を選択
  • イベントテンプレート:API Gateway AWS Proxy
  • イベント名:APIGatewayEvent1

image.png

設定したら、「作成」ボタンをクリックします。

「テスト」ボタンの左のコンボボックスで「APIGatewayEvent1」が選択された状態で、再度「テスト」ボタンをクリックします。

以下の画面のように「実行結果:成功」と表示されればOKです。
image.png

エラーがあった場合は、以下のような画面となります。「ログ出力」の項目の下の点線矩形内に、コードのどこでエラーが発生したかが表示されているので、ここを参考にコードを直しましょう。
image.png

API GatewayからAWS Lambda関数を駆動する。

ここまでできれば、次はAPI Gatewayをデプロイして、呼び出すことができます。
Designerパネルの「API Gateway」のところをクリックし、下に現れた「LambdaHelloPython」のリンクをクリックします。
image.png

すると、API Gatewayのマネジメントコンソールに移動します。先ほどAWS Lambdaの設定時に作成したAPIの設定画面が表示されます。
image.png

ここで、カミナリマークの上の「テスト」と書かれた部分
image.png
をクリックすると、以下のような画面に切り替わります。

image.png

ここで、「メソッド」に「GET」を指定し、他はそのままで、ページ最下部の「テスト」ボタンをクリックします。すると、以下のようにテスト結果がページの右側に表示されます。
image.png

ページ右側の結果部分に「ステータス:200」と表示され、レスポンス本文が以下のように、AWS Lambda関数でbodyに指定した内容が表示されていればOKです。

{
  "message": "Hello from AWS Lambda"
}

API Gatewayのデプロイ

では、作成したAPIをデプロイして、curlで叩いてみましょう。
「アクション」と書かれたボタンをクリックし、プルダウン表示されたメニューから「APIのデプロイ」を選択します。
image.png

すると、「APIのデプロイ」という画面が表示されるので、「デプロイされるステージ」に「dev」を指定して、「デプロイ」ボタンをクリックします。
image.png

すると、下図のような画面になり、「URLの呼び出し:」に続いてステージURLが表示されます。
image.png

このURLの後ろに/hello-world-pythonとつけることで、作成したAPIにアクセスできます。

curl <ステージURL>/hello-world-python

以下のように、PythonのAWS Lambda関数がbodyで返したレスポンスが表示されればOKです。

{"message": "Hello from AWS Lambda"}

デプロイの削除

上記手順で作ったAPIは「セキュリティ」を「オープン」に設定しているため。誰でもアクセスできてしまいます。第三者から不用意に大量にアクセスされないよう、動作確認ができたらステージを削除しておきましょう。

image.png

まとめ

PythonコードでAWS Lambda関数を記述しました。その関数が返す値を、API Gatewayが求める形式にしました。
作成したAWS Lambda関数をAPI Gatewayから呼び出すように設定しました。
APIをデプロイし、curlで叩くことで動作を確認しました。