はじめに
API Gateway + Lambda で Post された画像を Pillow で処理したかったため、AWS CDK で環境構築してみました。
API Gateway + Lambda(AWS CDK)
プロジェクト初期化
AWS CDK では API Gateway と Lambda を構築します。今回は Python で構築します。
プロジェクト初期化コマンドは以下の通りです。作成するディレクトリー名は任意です。今回は qiita-aag-image
としています。
$ mkdir qiita-aag-image
$ cd qiita-aag-image
$ cdk init --language=python
インフラコード
qiita_aag_image ディレクトリーに qiita_aag_image_stack.py が作成されているため、編集します。API Gateway や Lambda の Id は好きな名前をつけてください。
また、今回想定する画像形式は png とします。こちらも状況に合わせて変更してください。
from aws_cdk import core
from aws_cdk.aws_lambda import DockerImageFunction, DockerImageCode
from aws_cdk.aws_apigateway import LambdaRestApi
import os.path
dirname = os.path.dirname(__file__)
class QiitaAagImageStack(core.Stack):
def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
backend = DockerImageFunction(
scope=self, id='k-test-docker-function', code=DockerImageCode.from_image_asset(
directory='src',
), memory_size=1024, timeout=core.Duration.seconds(30))
LambdaRestApi(scope=self, id='k-test-api', handler=backend,
binary_media_types=['image/png'])
Dockerfile 作成
今回 Lambda では Docker イメージを動かすようにします。
$ mkdir src
$ cd src
$ touch Dockerfile
FROM public.ecr.aws/lambda/python:3.8
RUN pip install pillow
COPY app.py ./
CMD [ "app.handler" ]
Lambda コード
$ touch app.py
import base64
from io import BytesIO
import json
from PIL import Image
def handler(event, context):
data = event.get('body', '')
data = BytesIO(base64.b64decode(data))
image = Image.open(data)
# Pillow Image で処理する
# 今回は print のみ
print(image)
return {
'statusCode': 200,
'body': json.dumps({
'status': 'ok',
}),
}
デプロイ
事前に AWS のクレデンシャル情報の設定が必要です。設定方法はこの記事では取り扱いませんので、公式リンクを記載しておきます。
Configuration and credential file settings - AWS
# プロジェクトの Root ディレクトリーに戻ります
$ cd ..
$ cdk deploy
デプロイに成功すると以下のリソースが構築されます。
- ECR
- API Gateway
- Lambda
実行
Insomnia や Postman などお好きなツールから実行できます。今回は API Gateway の Binary Media Type に 'image/png' を指定しているので、同じ内容をリクエストヘッダーの Content-Type に追加します。
ログ
実行後に CloudWatch Logs を見てみると以下のように Pillow Image であるとログがでています。
<PIL.PngImagePlugin.PngImageFile image mode=L size=28x28 at 0x7F6487C6F3A0>
おわりに
API Gateway + Lambda で Post された画像を Pillow で処理できるようにするまでを解説しました。