awsで翻訳web apiを作る方法

2022/11/06に公開

本日行ったハンズオンはこちら

大まかな流れ

  1. Lambda Function を作成する
  2. LambdaとAmazon Translateを連携させる
  3. API Gatewayを作成する
  4. API GatewayとLambdaを連携させる
  5. DynamoDBを作成する
  6. DynamoDBとLambdaを連携させる(完成)

※Amazon Translateの無料枠: 1ヶ月に200万文字まで翻訳無料
※ハンズオンのLambdaはpythonで記述

lambdaの特徴

  • ec2はサーバー管理を意識しないといけないが、lambdaはコードのみ記述すればよい。
  • サーバーのプロビジョニング管理なし。
  • lambda本体はコンテナ上で実行される。
    • コンテナで同時に実行できるのは1リクエストまで
    • コンテナは再利用されるが利用可能なコンテナが無いときはコールドスタート
  • lambdaにはコールドスタートとウォームスタートがある
    • コールドスタートの流れ: コンテナ生成->デプロイ->ランタイム起動・初期化->メソッド起動
    • ウォームスタートの流れ: メソッド起動
    • lambda関数の書く場所によって分けられる
{ウォームスタート時は実行されない}
def lambda_handler(event, context):
	{コールドスタート・ウォームスタート両方実行される}

※ハンズオンのポイントのみ解説します。詳細な実装方法が知りたい方は上のハンズオンを行ってみてください。

Lambda Function を作成する

  • ひとまずdefaultの設定で作成する
  • loggerを使いたい場合はこちらを参考に設定する
    lambdaのソースを変更したら「deploy」というボタンを押さないと変更が保存されない
  • テスト実行でレスポンスの確認ができる

LambdaとAmazon Translateを連携させる

  • Python sdkのリファレンスを参考にAmazon Translateのclientを作成する

  • translate_textメソッドを利用する
    変換されたテキストはresponse.get('TranslatedText')で取得できる

  • lambdaに紐づいてるIAM RoleにAmazon TranslateのFullAccessポリシーを追加する

  • lambdaのテスト実行し、「こんにちは」が「Hi」に出力されることを確認する

API Gatewayを作成する

  • Rest APIタイプで作成する
  • リソースを作成する(sample)
  • メソッドを作成する(get)
    この時エンドポイントのタイプをMockに変更する
  • 統合レスポンスを選択し、Mapping Templatesに以下のjsonを記述する
{
    "statusCode": 200,
    "body": {
        {
            "report_id": 5,
            "report_title" : "Hello, world"
        },
        {
            "report_id": 7,
            "report_title" : "Good morning!"
        }
    }
}
  • テスト実行をし、モックのjsonが帰ることを確認する
  • apiをデプロイする。その時新しいステージ名(devとか)を作成する
  • 作られたエンドポイントURLをブラウザに貼り付け、モックのjsonが帰ることを確認する

API GatewayとLambdaを連携させる

先ほどのAPIにlambdaと連携するようのリソースを作成していく

  • リソースを作成する(translate)
  • メソッドを作成する(get)
    この時エンドポイントのタイプはLambdaのままにする。(この時lambda関数のトリガーにapi gatewayが紐づかれる)
    プロキシ統合にチェックをする
    プロキシ統合とは...インプットをそのままアウトプットにパススルーする設定。
    そのため統合レスポンスを編集することができない。
  • lambdaのresponseを統合レスポンスにあわせる
{
    statusCode: "...",            // a valid HTTP status code
    headers: { 
        custom-header: "..."      // any API-specific custom header
    },
    body: "...",                  // a JSON string.
    isBase64Encoded:  true|false  // for binary support
}
  • lambda関数の引数eventをAPI Gatewayにマッピングさせる参照
    API Gatewayから渡された文字列はevent['queryStringParameters']['input_text']で取得できる
  • lambdaでテスト実行をする。
    lambdaのテスト時に「apigateway-aws-proxy」を選択するとAPI Gatewayから返されるテンプレートが出てくる。そのうち、クエリパラメータの箇所を以下のように変更する
{省略}
"queryStringParameters": {
  "hoge_text": "こんばんは"
},
{省略}
  • API Gatewayでテストを実行する。クエリパラメータにinput_type='こんにちは'と入力し、Hiに変換されることを確認する
  • apiをdevステージにデプロイする
  • 作られたエンドポイントURLをブラウザに貼り付け、テストと同様の結果が帰ることを確認する

DynamoDBを作成する

以下設定する

  • table名: 「translate-history」
  • primary key: 「timestamp」(String)
  • attribute一覧:
    • timestamp(String): apiが呼ばれたタイムスタンプを保存(UTC時間)
    • input_text(String): 変換前のテキスト
    • output_text(String): 変換後のテキスト

DynamoDBとLambdaを連携させる(完成)

  • lambdaを編集する
    put_itemメソッドを使い、DynamoDBに保存する
    timestampはdatetime.datetime.now().strftime("%Y%m%d%H%M%S")で取得できる(事前にPythonの標準ライブラリであるdatetimeをインポートする必要がある)

  • lambdaのIAM RoleにDynamoDBのFullAccessポリシーをアタッチする

  • lambdaをテスト実行し、Dynamodbに保存されることを確認する。

  • 最後にAPI GatewayのエンドポイントURLで翻訳結果が帰ること、DynamoDBに実行履歴が保存されることを確認する

Discussion