Lambdaの非同期呼び出し
利用するもの
- S3(ストレージ)
- Lambda(プログラムを記述・実行する場所)
- AWS AI Services (AWSが提供しているAIモデル)
非同期呼び出しの流れ
例:音声ファイルの文字起こしを行い、ファイルに変換
- S3に音声ファイルをアップロード(トリガーとなる)
- Lambdaが実行される
- Lambdaのコードが呼び出したtranscribe(AWS AI Servicesの一つ)が実行される
非同期呼び出しの実装
上記の例を実装する流れ
- 音声ファイルを入れてトリガーとなるS3(*1)と、生成されるファイルを格納するS3(*2)を作成.
- lambda(関数)を作成する.
その際(*1)をトリガーに、出力場所を(*2)に設定する.(ロールにポリシーの追加も) - ドキュメントを参考にしてtranscribeのコードをlambdaに記述.
- 完成.音声ファイルを(*1)に入れると自動で文字起こしが実行されて(*2)にjson形式で格納される.
API Gatewayを使ってAPIを作成
例:入力した日本語を英語に翻訳するAPI
- リソースを作成
- リソースの中に統合タイプがlambda関数のGETメソッドを作成
API Gatewayからの入力・出力をパススルーさせるために、「lambdaプロキシ統合の使用」にチェックを入れる - 元の日本語テキストを入力するためのURLクエリ文字列パラメータを追加(必須にする)
- Lambda関数を書く
import json import boto3 translate = boto3.client('translate') def lambda_handler(event, context): # クエリパラメータから翻訳するテキストを読み取る input_text = event['queryStringParameters']['input_text'] response = translate.translate_text( Text=input_text, SourceLanguageCode='ja', #元のテキストは日本語 TargetLanguageCode='en', #翻訳後は英語 ) output_text = response.get('TranslatedText') return { 'statusCode': 200, 'body': json.dumps({ 'output_text': output_text }), 'isBase64Encoded': False, 'headers': {} } ~~~
- デプロイ
- 指定したステージを開くとURLが生成されており、URLの最後に
?input_text=こんばんは
を追加して開くと翻訳が返されたWebページが表示される
出力をDynamoDBに保存する場合
import json
import boto3
import datetime
translate = boto3.client('translate')
# 出力を保存するDynamoDBを指定
dynamo_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history')
def lambda_handler(event, context):
# クエリパラメータから翻訳するテキストを読み取る
input_text = event['queryStringParameters']['input_text']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode='ja', #元のテキストは日本語
TargetLanguageCode='en', #翻訳後は英語
)
output_text = response.get('TranslatedText')
# DynamoDBに追加
dynamo_translate_history_tbl.put_item(
Item = {
'timestamp': datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
'input_text': input_text,
'output_text': output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
ちなみにSAMテンプレートを使えば全部自動でやってくれる
SAMのビルド
sam init (最初だけ)
sam build
sam deploy --guided
ディレクトリ構造
environment
|--- hands-on-serverless-2
|--- translate-fuction
| |--- translate-function.py
|--- template.yaml
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2 #
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.7
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::Serverless::SimpleTable
Properties:
TableName: translate-history-2
PrimaryKey:
Name: timestamp
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
s3生成コマンド
aws s3 mb s3://hands-on-serverless-2
TranslateやDBなどをローカルで利用するには、cloud9のEC2インスタンスにTranslateやDBなどの権限を与えたロールを追加する必要がある。
(cloud9ダッシュボード→EC2インスタンス→アクション→セキュリティ→IAMロールを変更→追加→…)
Lambda関数のローカル実行コマンド
# サーバーを立てる
sam local start-lambda
# 別のターミナル行ってビルド
sam build
# 実行
aws lambda invoke --function-name "TranslateLambda" --endpoint-url "http://127.0.0.1:3001" --no-verify-ssl out.txt
APIのローカル実行コマンド
# サーバーを立てる
sam local start-api
# 別のターミナル行ってビルド
sam build
# 実行
curl http://127.0.0.1:3000/translate?input_text='こんにちは'
API生成コマンド
aws cloudformation package --template-file template.yaml --s3-bucket hands-on-serverless-2 --output-template-file packaged-template.yaml
aws cloudformation deploy --template-file ./packaged-template.yaml --stack-name hands-on-serverless-2 --capabilities CAPABILITY_IAM
AWS Amplify
↓全部ここ↓
基本的なバックエンド処理も認証機能もデプロイも、全部簡単なコマンドでできる。