AWS LambdaでPython基礎～Amazon S3とAmazon Translateを利用する

2022/4/6(水)に行われたAWSセミナー「Pythonの基礎から学ぶ!サーバーレス開発はじめの一歩」で構築したサーバレスアーキテクチャ環境の復習。

# 構成図
AWS Lambdaを起動し、S3バケットにアップロードした英語のテキストを、翻訳して返す簡易アプリケーションをPyhonで開発する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/b97c0559-a875-582e-111c-fd8f551440a1.png)

# 0.前提
[「AWS Cloud9でPython基礎～Amazon S3とAmazon Translateを利用する」](https://qiita.com/emiki/items/b95fad815d9f8e360dd0)で作成した s3 バケットが存在していること。
[「AWS Cloud9でPython基礎～Amazon S3とAmazon Translateを利用する」](https://qiita.com/emiki/items/b95fad815d9f8e360dd0)で作成したPythonコード`index.py`を、AWS Lambdaに移植していく。

# 1.Lambda関数の作成
AWSマネジメントコンソールでLambda画面を開き、「関数の作成」から以下設定し、その他項目はデフォルトで「関数の作成」をクリックする。

- 一から作成
- 関数名：`translate_file`
- ランタイム：Python3.9

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/bc597310-4cd9-df2c-80dd-38c506e9b99f.png)

Lambda関数作成直後は以下のコードが書かれている。

```py
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

このLambda関数では`lambda_handler()`関数が初めに実行される。
そのため、[AWS Cloud9でPython基礎～Amazon S3とAmazon Translateを利用する](https://qiita.com/emiki/items/b95fad815d9f8e360dd0)で作成したPythonコード`index.py`を以下の方針で移行する。

- 関数はそのまま移動する
- 関数外のプログラムはlambda_handler()関数内で実行する
- boto3のclientは関数の外に定義する

:::note info
**関数の外でboto3.clientを実行する理由**
boto3のclientは、`lambda_handler()`の外部で定義すると、複数回Lambda関数が呼び出された際に初期化されたままとなり、実行が効率的になる。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtimes-context.html 
:::

```py:lambda_function.py

import boto3

s3_client = boto3.client('s3')
translate_client = boto3.client('translate') 


def read_s3_file():
    input_object = s3_client.get_object(Bucket='learn-python-20220417-xxxxx-input', Key='sample_file.txt')
    input_object_byte = input_object['Body'].read()
    input_object_text = input_object_byte.decode()
    return input_object_text
 
 
def honyaku(text, source_language_code, target_language_code):
    response = translate_client.translate_text(
        Text=text, 
        SourceLanguageCode=source_language_code, 
        TargetLanguageCode=target_language_code  
        )
    
    print(response['TranslatedText'])
    return response['TranslatedText']


def write_s3_file(output_text):
    s3_client.put_object(Bucket='learn-python-20220417-xxxxx-output', Key='upload.txt', Body=output_text.encode())


def lambda_handler(event, context):
    text = read_s3_file()
    source_language_code='en'
    target_language_code='ja'
    translated_text = honyaku(text, source_language_code, target_language_code) 
    write_s3_file(translated_text)
```

「Deploy」をクリックしてコードを保存する。

# 2.Lambda関数への権限付与
このままだとLambda関数がS3バケットへのアクセス権限と Amazon Translate へのアクセス権限を保持していないためエラーになる。

設定タブから[アクセス権限]-[実行ロール]のリンクをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/fb2df652-929f-a293-9adb-f3bc1c8382f7.png)

[アクセス許可を追加]-[ポリシーをアタッチ]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/c8839b51-6079-5732-e50c-66dec7c1db73.png)

「AmazonS3FullAccess」にチェックを入れ、「ポリシーをアタッチ」をクリックする。

:::note alert
ここでは操作を簡単にするためにS3へ全ての操作を許可する権限を付与しているが、必要なリソースに必要な権限のみ付与することがベストプラクティスであることに注意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/da0e7efa-a511-6fe5-ed32-4fa2538cca0c.png)
:::

続けて Amazon Translate への権限を付与する。
[アクセス許可を追加]-[ポリシーをアタッチ]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/7a2382bc-ab96-cb6f-9f5e-02cd3ef0e86d.png)

「TranslateReadOnly」にチェックを入れ、「ポリシーをアタッチ」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/99302c45-0c24-0509-016d-38cf255bcd1b.png)

# 3.Lambda関数実行
Lambda 関数の画面に戻り、テストタブから「テスト」をクリックする。
成功と表示され、ログに翻訳後の文章が表示されていることが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/74219ea5-2502-e332-fdcc-2728de1be3b4.png)

S3バケットを見ると、「upload.txt」の時間が更新されているのが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/e136141c-79b2-e5e2-f158-6371ad5e68d6.png)

# 参考
[AWS Cloud9でPython基礎](https://qiita.com/emiki/items/65eb26492be5315d929d)
[AWS Cloud9でPython基礎～ファイルの読み書き](https://qiita.com/emiki/items/f93bddb4a1fd76b102b5)
[AWS LambdaでPython基礎](https://qiita.com/emiki/items/5daa0e31b8a8fa7c680a)
[AWS Cloud9でPython基礎～Amazon S3を利用する](https://qiita.com/emiki/items/7433971c9f1ee03dd9ea)
[AWS Cloud9でPython基礎～Amazon S3とAmazon Translateを利用する](https://qiita.com/emiki/items/b95fad815d9f8e360dd0)
[AWS LambdaでPython基礎～Amazon S3とAmazon Translateを利用する](https://qiita.com/emiki/items/0f9bbddd6f4cd475f12b)