PillowをAWS Lambda + Python + Serverless Frameworkで動かす

画像を処理できるPillowをAWS Lambda + Python + Serverless Frameworkの環境で動かしてみました。

AWS Lambda + Python + Serverless FrameworkにPythonのパッケージをインストールする方法は前回の記事に書きました。

AWS Lambda + Python + Serverless FrameworkのLayerにpipインストール

これに従うだけです。

requirements.txt はこの1行。

Pillow

serverless.yml は次のとおり。

service: sample

frameworkVersion: '2'

provider:
  name: aws
  runtime: python3.8
  lambdaHashingVersion: 20201221
  region: ap-northeast-1

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi: "*"
    layers:
      - { Ref: PythonRequirementsLambdaLayer }

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    layer: true

handler.pyは次のとおり。画像ファイルをPillowで生成してそれをHTTPレスポンスします。Lambdaからのレスポンス時はBASE64エンコードが必要です。API Gatewayがそれをデコードしたうえでブラウザにレスポンスしてくれます。

import base64
import io

import PIL
import PIL.Image
import PIL.ImageDraw

def hello(event, context):
    print("Hello, Pillow!")
    print(PIL.__version__)
    # これはCloudWatch Logsに書き出される

    image = PIL.Image.new('RGB', (100, 100))
    draw = PIL.ImageDraw.Draw(image)

    draw.rectangle((20, 20, 80, 80)) # 質素な四角形を作成

    # バイナリイメージを作成
    output = io.BytesIO()
    image.save(output, format = "JPEG")
    responseBody = output.getvalue()

    # BASE64エンコード
    responseBody = base64.b64encode(responseBody).decode("utf-8")

    return {
        "statusCode": 200,
        "headers": {
            "Content-Type": "image/jpeg",
        },
        "body": responseBody,
        "isBase64Encoded": True,
    }

デプロイ。

$ serverless deploy -v

ローカルに手動でpipインストールしたりせず、全部Serverless Frameworkがいろいろやってくれます。

作成されたAPI Gatewayにブラウザでアクセスすると、次のような画像が表示されます。上記Pythonコードにある draw.rectangle((20, 20, 80, 80)) の絵です。

f:id:suzuki-navi:20210202163612p:plain

CloudWatch Logsには以下が書き出されていました。

Hello, Pillow!
8.1.0