らくがきちょう

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

AWS API Gateway + Lambda + mangum + FastAPI な Python アプリケーションに POST された JSON を処理する

以前に mangum + FastAPI で ASGI な Python アプリケーションを AWS Lambda + API Gateway 上で動かすというメモを書きました。 mangummangum-cli を使うと FastAPI を使った Web アプリケーションを AWSLambdaAPI Gateway を使って簡単に公開することが出来ます。

mangum-cli が無い場合は作成したアプリケーションを手動でアプリケーションをアップロードする必要があります。 CloudFormation を使うにしてもテンプレートを作成する必要があり、面倒です。 mangum-cli があればこれらの作業を自動化出来、手間なく、迅速にアプリケーションを配置することが出来ます。

FastAPI で REST API のエンドポイントを作成する場合、POST リクエストを受け付ける必要があります。 こういった場合の「POST された JSON を FastAPI な Python アプリケーションで処理する方法」をメモしておきます。

CLI から curl を使って JSON を POST する

data.json というファイルを CLI から curl を使って POST するには以下のように実行します。

curl -H 'Content-Type:application/json' -d @user.json [URL]

単純な構造の JSON を処理する場合

単純な構造の JSON を処理するケースを考えます。

JSON ファイル

以下のような JSON を想定します。

{
    "user_id": 1,
    "name": "suzuki"
}

サンプルコード

サンプルコードは以下のようになります。

from fastapi import FastAPI
from mangum import Mangum
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    user_id: int
    name: str

@app.post("/")
def read_root(user: User):
    return {"user_id": user.user_id, "name": user.name}

handler = Mangum(app, enable_lifespan=False)

実行結果

実行結果は以下の通りです。

$ curl -H 'Content-Type:application/json' -d @user.json https://0123456789.execute-api.ap-northeast-1.amazonaws.com/Prod
{"user_id":1,"name":"suzuki"}

やや複雑な構造の JSON を処理する場合

やや複雑な構造の JSON を処理する場合を考えます。

JSON ファイル

以下のような JSON を想定します。

{
    "user_id": 1,
    "detail": {
        "name": "suzuki",
        "heigth": 170,
        "weight": 70
    }
}

サンプルコード

サンプルコードは以下のようになります。

from fastapi import FastAPI
from mangum import Mangum
from pydantic import BaseModel

app = FastAPI()

class UserDetails(BaseModel):
    name: str
    height: int
    weight: int

class User(BaseModel):
    user_id: int
    details: UserDetails

@app.post("/")
def read_root(user: User):
    return {
        "user_id": user.user_id,
        "name": user.details.name
    }

handler = Mangum(app, enable_lifespan=False)

実行結果

実行結果は以下の通りです。

$ curl -H 'Content-Type:application/json' -d @user.json https://0123456789.execute-api.ap-northeast-1.amazonaws.com/Prod
{"user_id":1,"name":"suzuki"}