【AWS初学者向け】翻訳WEB APIを作成してみた(ハンズオン)
Hands on beginners を参考に実装してみました

1.はじめに
AWSハンズオン資料集の中から「サーバーレスアーキテクチャで翻訳 Web API を構築する」を試してみて結構楽しかったので
- AWS初学者向けに構築フロー
- つまずきポイント
- 個人的に修正してみた箇所
の3点を共有します。
上記、URLからAWS初学者の方はぜひトライしてみてください。
参考ドキュメント
- https://boto3.amazonaws.com/v1/documentation/api/latest/index.html
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-integration-settings-integration-response.html
2. 構成
(ハンズオン資料より抜粋)
ブラウザで翻訳語の文字列が返ってくれば完成
3. LambdaからAWS Translateを呼び出す
LambdaからAWS Translateを呼び出すためには、python SDK のboto3を使用します。
https://boto3.amazonaws.com/v1/documentation/api/latest/index.html
公式ドキュメントからtranslateの項目を確認し、使い方を参照します。
必須パラメータは、下記の通り
response = client.translate_text(
Text='string',
SourceLanguageCode='string',
TargetLanguageCode='string',
}
)
レスポンスは下記のように返ってくるとのこと
sample code
import json
import boto3
translate = boto3.client('translate')
def lambda_handler(event, context):
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
}),
}
4. API Gatewayを設定し、Lambdaのソースコードを修正する
アクションからリソースの作成→メソッドの作成を行う
クエリ文字列パラメータの設定
API Gateway統合レスポンスで検索すると、 Lambda プロキシ統合で、Lambda 関数は以下の形式で出力を返す必要があることがわかります。
{
statusCode: "...", // a valid HTTP status code
headers: {
custom-header: "..." // any API-specific custom header
},
body: "...", // a JSON string.
isBase64Encoded: true|false // for binary support
}
コード修正
import boto3
translate = boto3.client('translate')
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': {}
}
5. DynamoDBに入力テキストと変換後テキストを格納する
事前にテーブルを作成する必要あり
修正箇所
import datetime
dynamodb = boto3.resource('dynamodb')
translate_history_table = dynamodb.Table('tranlate-history')
translate_history_table.put_item(
Item = {
'timestamp': datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
'input_text': input_text,
'output_text': output_text
}
)
6. Lambda関数全体
import json
import boto3
import datetime
translate = boto3.client('translate')
dynamodb = boto3.resource('dynamodb')
translate_history_table = 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')
translate_history_table.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': {}
}
7. つまずきポイント
https://*******.execute-api.ap-northeast-1.amazonaws.com/Stage/translate?input_text=こんにちは
あれ、返ってこない、、、
結論:dynamoDBへの実行ロールを付与し忘れ
余談
api gatewayは、作成するときに自動的にロール付与してくれたな。。
8. 個人的に工夫した点
任意のステータスコードを返すようにLambda関数にエラーハンドリングを実装
import json
import boto3
import datetime
import logging
translate = boto3.client('translate')
dynamodb = boto3.resource('dynamodb')
translate_history_table = dynamodb.Table('tranlate-history')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text']
# 追加箇所
try:
response = translate.translate_text(
Text=input_text,
SourceLanguageCode='ja',
TargetLanguageCode='en'
)
except Exception :
raise ExtendException(400, "Bad Request")
output_text = response.get('TranslatedText')
translate_history_table.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': {}
}
# 追加箇所
class ExtendException(Exception):
def __init__(self, statusCode, description):
self.statusCode = statusCode
self.description = description
def __str__(self):
obj = {
"statusCode": self.statusCode,
"description": self.description
}
return json.dumps(obj)
9. まとめ
SAA資格勉強程度の知識しかなかった私にはとても有用なハンズオンでした。
手を動かして構築してみることは大切ですね。何より楽しい!!
次は、SAMでデプロイの自動化を実装したいと思います。