LoginSignup
1
0

More than 1 year has passed since last update.

AWS Lambda で API Gateway 経由して Python で POST データを受け取る

Posted at

Lambda 側でも POST データを受け取れます。
application/x-www-form-urlencoded で送信されたPOSTデータを受信してみます。

lambda_function.py
import json
import urllib.parse

def lambda_handler(event, context):
    # TODO implement

    # イベントとコンテキストの内容を出力
    print( "event:" , event )
    print( "context:", context )

    # QueryString をパースする
    strBody = event.get('body')
    param = urllib.parse.parse_qs(strBody)

    # パラメータを取得する
    strParam1 = param['param1']
    strParam2 = param['param2']

    # パラメータの内容を出力する
    print( "strParam1:", strParam1 );
    print( "strParam2:", strParam2 );

    return {
        'statusCode': 200,
        'body': json.dumps('ok')
    }

event.body に格納された文字列を urllib で parse する必要があります。

run.sh
#!/bin/sh

TARGET='https://xxxx.execute-api.ap-northeast-1.amazonaws.com/default/lambda-test-04'

API_KEY="XXXX"

PARAM1="param1=aaa"
PARAM2="param2=bbb"


curl -o - "${TARGET}" -d ${PARAM1} -d ${PARAM2} --header "x-api-key:${API_KEY}"

実行結果として CloudWatch にパラメータが出力されます。

strParam1: ['aaa']
strParam2: ['bbb']

パースした結果は配列として格納されているようです。同じパラメータ名の変数がPOSTされた場合には配列で取れるようです。

では、multipart/form-data でファイルをPOSTすることができるかを確認しているのですが、ネットを検索するとできるようなことも書いてあるのですが、うまく設定できず未確認の状態です。

ただ、こちらでアップロードした方法は下記の方法で REST API にバイナリファイルを直接送りつけるということはできるようです。

下記の例は、lambda にPOSTした画像ファイル(test.jpg)をS3のtokyo20230412バケットに格納するサンプルです。

lambda_function.py
# -*- coding: utf-8 -*-

import json
import urllib.parse
import boto3
import base64

def lambda_handler(event, context):
    # TODO implement

    # イベントとコンテキストの内容を出力
    print( "event:" , event )
    print( "context:", context )

    # パラメータを取得
    param = json.loads( event['body'] )

    file_data = param['file']
    data = base64.b64decode( file_data.encode( 'utf8' ) )

    client = boto3.client('s3')
    client.put_object(Body=data,Bucket='tokyo20230412',Key='test.jpg')

    return {
        'statusCode': 200,
        'body': json.dumps('ok')
    }

上記のlambdaにPOSTをするPythonコードが下記のものになります。
このコードをローカルで実行するとAWS上のLambdaを経由してS3に画像ファイルが格納されます。

test.py
import json
import requests
import base64

image = "header.jpg"
data = open(image, 'rb').read()
encoded_data = base64.b64encode(data).decode('utf-8')

url = 'https://xxxx.execute-api.ap-northeast-1.amazonaws.com/default/lambda-test-05'

payload = {'file': encoded_data}
headers = {'x-api-key': 'XXXX'}

response = requests.post(url, data=json.dumps(payload), headers=headers)

print( response )

view を掌るブラウザ側からは JavaScript を使ってPOSTをすることになると思うので、multipart/form-data を使用できなくても、入力項目とファイルを個別のLambdaにPOSTすればよいだけなのですが、PHPで記述した既存のWebアプリケーションをServer less に移行する場合は改修が必要となるポイントとなります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0