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

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

# 構成図
Amazon S3バケットに格納された英語のテキストを AWS Cloud9で読み取り、Amazon Translate で翻訳して S3バケットにアップロードする簡易アプリケーションをPyhonで開発する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/02352c94-495b-14e4-a4b8-0bd8d175ac31.png)

# 1. S3 バケットの準備

翻訳する前のファイルを入れる S3 バケットと、翻訳語のファイルを入れるS3 バケットを作成しておく。

- learn-python-YYYYMMDD-xxxxx-input
- learn-python-YYYYMMDD-xxxxx-output

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/ab115e69-3878-79cf-ee2e-08e8fe327d65.png)

[AWS Cloud9でPython基礎～Amazon S3を利用する 1-2.ファイルのアップロード](https://qiita.com/emiki/items/7433971c9f1ee03dd9ea#1-2%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89) を参考に、以下内容を入力して保存した`sample_file.txt` ファイルを、AWS ツールキットで S3 バケット`learn-python-YYYYMMDD-xxxxx-input` にアップロードする。

```:sample_file.txt
I want to be able to use Python!
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/4af91724-4227-cd3c-83ac-5e14aef4121a.png)

# 2. S3 にあるファイルの読み込み

S3 バケット `learn-python-YYYYMMDD-xxxxx-input` から `sample_file.txt` ファイルを読み込むPythonコードを書く。ファイルが多くなってきたのでフォルダを作成してPythonコードを格納する。

Cloud9 でAWSツールキットが開いていたら、フォルダマークをクリックしてディレクトリの表示に戻す。
何もないところで右クリックし、「New Folder」で新しいフォルダを`translate`と名前を付けて作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/5d017e25-d98f-a204-62dd-ee34ec7ba7d7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/ac2e7181-b18b-47bf-7c71-e4a4b4383241.png)

ファイルを読み込む `index.py` ファイルを、作成した `translate` フォルダに新しく作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/3f1be520-8247-330e-bb92-a3eb000c9a5b.png)

[AWS Cloud9でPython基礎～Amazon S3を利用する 1-3.Boto3を使ってS3のファイルを読み込む](https://qiita.com/emiki/items/7433971c9f1ee03dd9ea#1-3boto3%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6s3%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80)で作成した`read_file.py`を以下のように書き換える。

- `Bucket`と`Key`を今回対象のバケット名と`sample_file.txt`に変える
- print文を削除
- 変数`text`に`read_s3_file()`の戻り値を格納する
- 確認のため最後に読み込んだファイルの中身をprint文で表示する

```py:index.py①
import boto3

def read_s3_file():
    s3_client = boto3.client('s3')
    
    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
    
text = read_s3_file()
print(text)
```

以下コマンドで実行する。

```
cd translate/  # translate フォルダに移動
python index.py 
```

実行結果

```
I want to be able to use Python!
```

# 3. ファイルから読み込んだ文章の翻訳

[AWS Cloud9でPython基礎 2-4-2.キーワード引数](https://qiita.com/emiki/items/65eb26492be5315d929d#2-4-2%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E5%BC%95%E6%95%B0)で作成した`positional_arguments.py`を参考に、`index.py`を編集する。

- `index.py`に`honyaku()`関数を追加
- `honyaku()`関数を、ファイルから読み込んだ文字列が格納されている変数`text`を使って呼び出す

```py:index.py②
import boto3

def read_s3_file():
    s3_client = boto3.client('s3')
    
    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
 
 
 # positional_arguments.py から honyaku() 関数を貼りつけ
def honyaku(text, source_language_code, target_language_code):

    client = boto3.client('translate') 

    response = client.translate_text(
        Text=text, 
        SourceLanguageCode=source_language_code, 
        TargetLanguageCode=target_language_code  
        )

    print(response)
  # honyaku() 関数ここまで

text = read_s3_file()

 # キーワード引数を設定
source_language_code='en'
target_language_code='ja'

 # honyaku()関数を、引数を使って呼び出し
honyaku(text, source_language_code, target_language_code) 
```

編集した`index.py`の実行結果

```
{'TranslatedText': 'Pythonを使えるようになりたい！', 'SourceLanguageCode': 'en', 'TargetLanguageCode': 'ja', 'ResponseMetadata': {'RequestId': '295ac75c-1c16-4fd1-b0ef-45xxxxxxxxxx', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '295ac75c-1c16-4fd1-b0ef-45xxxxxxxxxx', 'cache-control': 'no-cache', 'content-type': 'application/x-amz-json-1.1', 'content-length': '115', 'date': 'Sun, 17 Apr 2022 09:31:49 GMT'}, 'RetryAttempts': 0}}
```

翻訳されて、Pythonの辞書型で値が返ってきていることがわかる。

次に、ユーザー定義関数`honyaku()`を、`'TranslatedText'`の部分だけを返すように書き換える。
Pythonの辞書型で値が返ってきているので、[AWS Cloud9でPython基礎 2-1-3.辞書型（dict）](https://qiita.com/emiki/items/65eb26492be5315d929d#2-1-3%E8%BE%9E%E6%9B%B8%E5%9E%8Bdict)を参考に、辞書型の出力の中から `key='TranslatedText'`部の `value` だけ返すように書き換える。

```py:index.py③
import boto3

def read_s3_file():
    s3_client = boto3.client('s3')
    
    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):

    client = boto3.client('translate') 

    response = client.translate_text。
        Text=text, 
        SourceLanguageCode=source_language_code, 
        TargetLanguageCode=target_language_code  
        )
    
    # ここで、辞書型の出力の中から key='TranslatedText'部の value だけ返すように書き換え  
    print(response['TranslatedText'])

text = read_s3_file()

source_language_code='en'
target_language_code='ja'

honyaku(text, source_language_code, target_language_code) 
```

編集した`index.py`の実行結果

```
Pythonを使えるようになりたい！
```

S3 バケットから読みとったファイルの内容を、日本語に翻訳して返すことができた。

# 4. 翻訳した文章をS3 バケットへ書き込む

[AWS Cloud9でPython基礎～Amazon S3を利用する 2-1.Boto3でS3にファイルを作成する](https://qiita.com/emiki/items/7433971c9f1ee03dd9ea#2-1boto3%E3%81%A7s3%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)で作成した`write_file.py`を参考に`index.py`を書き換える。

- ユーザー定義の`honyaku()`で戻り値を返すよう変更する
- ユーザー定義の`honyaku()`関数を呼び出す側でも戻り値を変数で受け取るようにする

```py:index.py④
import boto3

def read_s3_file():
    s3_client = boto3.client('s3')
    
    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):

    client = boto3.client('translate') 

    response = client.translate_text(
        Text=text, 
        SourceLanguageCode=source_language_code, 
        TargetLanguageCode=target_language_code  
        )
    
    print(response['TranslatedText'])
    
    # honyaku()関数で戻り値を返すようにreturn追加 
    return response['TranslatedText']

text = read_s3_file()

source_language_code='en'
target_language_code='ja'

 # 翻訳済みの文章を変数translated_text に格納
translated_text = honyaku(text, source_language_code, target_language_code) 
```

- `write_s3_file()` 関数を追記する

```py:index.py⑤
import boto3

def read_s3_file():
    s3_client = boto3.client('s3')
    
    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):

    client = boto3.client('translate') 

    response = client.translate_text(
        Text=text, 
        SourceLanguageCode=source_language_code, 
        TargetLanguageCode=target_language_code  
        )
    
    print(response['TranslatedText'])
    return response['TranslatedText']

 # write_s3_file()関数を追加
def write_s3_file():
    s3_client = boto3.client('s3')
    
    output_text = 'This is uploaded.'.encode()
    
    s3_client.put_object(
    Bucket='<バケット名>', 
    Key='upload.txt', 
    Body=output_text,
    )
 # write_s3_file()関数ここまで

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()`がファイルを書き込むバケット名を`learn-python-YYYYMMDD-XXXXX-output`に変更する
- 関数`write_s3_file()`がS3バケットにファイルとして書き込む文字列を受け取れるようにパラメータを設定する
- 設定したパラメータを`client.put_object()`にバイトオブジェクトとして、キーワード`Body`に渡す
- 関数`write_s3_file()`を呼び出す。このとき、変数`translated_text`を引数として渡す

```py:index.py⑥
import boto3

def read_s3_file():
    s3_client = boto3.client('s3')
    
    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):

    client = boto3.client('translate') 

    response = client.translate_text(
        Text=text, 
        SourceLanguageCode=source_language_code, 
        TargetLanguageCode=target_language_code  
        )
    
    print(response['TranslatedText'])
    return response['TranslatedText']

 # write_s3_file()関数を変更
 # 関数`write_s3_file()`がS3バケットにファイルとして書き込む文字列を受け取れるようにパラメータ(output_text)を設定する
def write_s3_file(output_text):
    s3_client = boto3.client('s3')
    
    s3_client.put_object(
    Bucket='learn-python-20220417-xxxxx-output', 
    Key='upload.txt', 
    # 設定したパラメータを`client.put_object()`にバイトオブジェクトとして、キーワード`Body`に渡す
    Body=output_text.encode(),
    )
 # write_s3_file()関数ここまで

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`を引数として渡す
write_s3_file(translated_text)
```

実行結果

```
Pythonを使えるようになりたい！
```

左サイドバーのAWS ツールキットでS3バケット`learn-python-YYYYMMDD-xxxxx-output`に`upload.txt`があることが確認できればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/1ea1058c-4e6b-e6fd-edea-00a2efc2b996.png)

マネジメントコンソールでS3 バケットから`upload.txt`をダウンロードしてファイルの中身を確認すると、翻訳後の文章が記載されているのが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/4368bb12-166b-8738-dd76-1c68fb7f1789.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)