【AWS入門】初めてのLambdaはTranscribe♪

これは備忘録のために、参考のとおりにやってみた記録です。
参考記事はすっきり書かれていてわかっている人なら簡単なんだと思いますが、AWS初心者には難しい内容でした。そのあたりを泥臭く解説したいと思います。
なのでやったことは、最終的に参考記事のまんまです。
【参考】
・[S3 → Lambda → Transcribe → S3 で文字起こしパイプラインを作成する](https://qiita.com/leomaro7/items/ad9726391d547ea3bcfd)
###やったこと
・1 S3に(input)用のバケットを作成
・2 Lambdaを開く
・3 Lambda関数の定義と意味
・4 CloudWatch Logsの見方
・5 S3に(output)用のバケットを作成
・6 Lambda修正
・7 実行ロールの変更の仕方
・8 Lambda functionを編集する
・9 Transcriptionの確認の仕方
###・1 S3に(input)用のバケットを作成・5 S3に(output)用のバケットを作成
AWSの左上のサービスを押すと全サービスが表示されて、ここからいろいろなメニューを選択できる。
その中で、ストレージのs3を選ぶと、s3のバケットを作成できるページに飛べるのでそこで作成する。セキュリティは全部禁止でも動くと思う（オブジェクトは公開可能にしている）。
適当なバケット名でインプット用とアウトプット用を作成する。
###・2 Lambdaを開く
上記と同じように全サービス表示して、今度はコンピューティングのLambdaを開く。
関数の作成のページが開く
もし開かなければ、その関数の作成をクリックする。
すると、参考①の絵のページ飛びます。
ここで、[設計図を使用]―[s3-get-object-python]-[設定]で次の画面に行けます。
###・3 Lambda関数の定義と意味
そもそも大前提として、**Lambda関数は何らかのTriggerを拾って動作する関数をサーバーレスで定義する方式で、完全に動いた分の料金がかかる従量制のサービスです。**
というわけで、ほぼ単一機能の関数を定義します。

いよいよ関数の動きの定義をします。
関数名；一意ならなんでもよさそうです
ロール名；これ一意な必要がある。関数消しても消えないので別途消す必要がある
S3トリガー；input用バケット名を入力
トリガーの有効化；チェックを入れる
以下のスケルトンが吐かれているが、この関数はもう動作する関数であることが分かる。すなわち、インプットのバケットに何かを配置（転送）するとログが記録されることが分かる。
内容を見てみると以下のとおり
まず、Libは以下のとおり

```py
import json
import urllib.parse
import boto3
```
s3オブジェクトの取得

```py
print('Loading function')
s3 = boto3.client('s3')
```
lambda_handler関数は、#に書いてある動作をする。
すなわち、eventからオブジェクトをゲットして、その内容を示す。
bucketは、上で定義したs3バケット名を返す。
keyがファイル名を返す。
responseにそのバケットに配置されたファイル名などを取得する。
そのコンテンツタイプをリターンしている。
Exception以下はエラールーチンである。

```py
def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))
    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e
```
###・4 CloudWatch Logsの見方
関数を作成すると、関数のページが出来る。
そこへ入ると、[設定][アクセス権限][モニタリング]となっており、下にコードが書かれている。
その[モニタリング]を選ぶ。
そして、いくつかのグラフがあり、その下にCloudWatch Logs Insightsというのが表示されている。
ここで、上記のインプットバケットにec2などから何か配置（転送）してみる。
すると、上記のLambda関数が動いて、このCloudWatch Logsに時々刻々動いた記録が表示される。エラーなども吐かれる。
ということで、少なくとも動作している確認ができる。
※たぶん正常動作だと思われる
###・6 Lambda修正
いよいよLambda関数を本物にする。
今回は、参考①のアプリをコピペして、インプットとアウトプットのバケット名を変更するだけでいいと思う。
try内の実際にトリガーが来た時の動作を見ておく。
ここで、一番工夫されているのはTranscriptionJobNameをトリガーがかかった時刻毎に生成して、一意を保っているところです。したがって、生成されたjsonもその時刻が分かります。bucketがインプットバケットであり、ファイル名がkeyだということで以下のコードは理解できると思います。
そして出力ファイルは、OutputBucketNameで定義したバケットに出力されます。

```py
        transcribe.start_transcription_job(
            TranscriptionJobName= datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '_Transcription',
            LanguageCode='ja-JP',
            Media={
                'MediaFileUri': 'https://s3.ap-northeast-1.amazonaws.com/' + bucket + '/' + key
            },
            OutputBucketName='lamoutput'
        )
```
###・7 実行ロールの変更の仕方
[アクセス権限]を選ぶ。実行ロールが表れる。
それをクリックすると、実行ロールのアクセス権限が表れ、PermissionsPolicyが表れる。
ここに、
 AmazonS3FullAccess
 AmazonTranscribeFullAccess
を追加する。
追加の仕方は、[ポリシーをアタッチする]をクリックし、検索に上記を入れれば出てくるので、左のチェックをして、アタッチするで追加される。
###・8 Lambda functionを編集する
6と同じだが、関数のページで下のコードを直接修正して、SAVEする。
###・9 Transcriptionの確認の仕方
この状態で、何かのmp3ファイルをインプットに配置すると、そのTranscribeした結果がアウトプットにjsonファイルが入っていると思う。
少し時間かかるように思うが、自前のプログラムよりも早く出力してくれた。
様子は、上のCloudWatch Logsを見ていると現在の状況が見える。
ちなみに、アウトプットバケットでは、リロードしないと見えないことがあるので注意です。
そして、そのjsonファイルを公開するとダウンロードなどが簡単にできる。
また、単に開いたら文字化けしていた。メモ帳で開いたら綺麗に中身が見えました。
さらに、ダウンロードしたjsonファイルをpandasで読み込んで、Transcribeした文章を確認するのが綺麗たと思う。
ここまで上記の関数でやろうと考えたが、なかなかむつかしそうなので今夜は断念。
###まとめ
・Lambda関数デビューが出来た

・変換が速いのでPollyについても実施して会話アプリに応用したい
・Pollyも同じような作りでやってみようと思う