Amazon Web Services ブログ

Amazon S3 Object Lambda を使用してコンテンツを動的に翻訳する

この投稿はシニアソリューションアーキテクト、Sandeep Mohantyによって書かれました。

最近発表された Amazon S3 Object Lambda は、S3 バケット内のデータを動的に変換することで多くの可能性を生み出します。S3 Object Lambda を他の AWS サーバーレスサービスと共に使用して、S3 に保存されているコンテンツをさまざまなクリエイティブな方法で変換できます。1 つの例は、Amazon Translate で S3 Object Lambda を使用して、オンデマンドで S3 バケットのコンテンツを翻訳して提供することです。

Amazon Translate は、高速でカスタマイズ可能な言語翻訳を提供するサーバーレス機械翻訳サービスです。Amazon Translate を使用すると、ウェブサイトやアプリケーションなどのコンテンツをローカライズして、さまざまなユーザーにサービスを提供できます。

Amazon Translate で S3 Object Lambda を使用すると、ソースからターゲット言語への可能なすべての組み合わせについて、コンテンツを事前に翻訳する必要はありません。代わりに、データ駆動モデルを使用して、ほぼリアルタイムでコンテンツを変換できます。これにより、複数の言語固有のアプリケーションに同時に提供できます。

S3 Object Lambda を使用すると、クライアントアプリケーションによって S3 からオブジェクトを取得するときに、Lambda 関数を使用してデータを処理および変換できます。S3 GET オブジェクトリクエストは Lambda 関数を呼び出し、特定の要件を満たすようにコンテンツを変換するようにカスタマイズできます。

たとえば、世界中からアクセスがあるWeb サイトまたはモバイルアプリケーションを実行する場合は、複数の言語で翻訳を提供する必要があります。このアプローチを使用して、フォーム、免責事項、商品説明などのアーティファクトを翻訳して、多様なグローバルオーディエンスにサービスを提供できます。

ソリューションアーキテクチャ

以下に示すのは、動的コンテンツをオンデマンドで変換するサンプルアプリケーションの概要レベルのアーキテクチャ図です。

Solution architecture

この例では、オブジェクトの S3 GET リクエストをとらえる S3 Object Lambda を作成します。そして、ファイルをS3 オブジェクトキーに引数として渡されたターゲット言語に変換します。大まかなレベルでは、手順を次のように要約できます。

  1. Amazon Translate を使用して、ソース言語からターゲット言語にデータを翻訳する Lambda 関数を作成します。
  2. S3 コンソールから S3 Object Lambda アクセスポイントを作成します
  3. ステップ 1 で作成した Lambda 関数を選択します。
  4. サポートする S3 アクセスポイントを提供して、S3 Object Lambda に元のオブジェクトへのアクセスを許可します。
  5. S3 GetObject API を呼び出して S3 からファイルを取得し、実際の S3 バケット名ではなく、Object Lambda アクセスポイント ARN をバケット名として渡します。

Lambda 関数の作成

最初のステップでは、ラムダ関数 DynamicFileTranslation を作成します。この Lambda 関数は S3 GET オブジェクト API 呼び出しによって呼び出され、要求されたオブジェクトを翻訳します。ターゲット言語は、S3のオブジェクトキーに付加された引数として渡され、取得するオブジェクトに応じます。
たとえば、S3 GetObject API 呼び出しで渡されたオブジェクトキーが「ContactUs/contact-us.txt#fr」のようにカスタマイズされている場合、シャープ記号の後の文字はターゲット言語のコードを表します。この場合、’fr’ はフランス語です。サポートされている言語と言語コードの完全なリストは、こちらにあります。
この Lambda 関数は、S3 内のオブジェクトのコンテンツをターゲット言語に動的に変換します。

Lambda 関数のコードは次のとおりです。

import json 
import boto3 
from urllib.parse import urlparse, unquote 
from pathlib import Path 

def lambda_handler(event, context):
    print(event)
    
    # Extract the outputRoute and outputToken from the object context 
    object_context = event["getObjectContext"] 
    request_route = object_context["outputRoute"] 
    request_token = object_context["outputToken"]
    
    # Extract the user requested URL and the supporting access point arn
    user_request_url = event["userRequest"]["url"] 
    supporting_access_point_arn = event["configuration"]["supportingAccessPointArn"]
    
    print("USER REQUEST URL: ", user_request_url)
    
    # The S3 object key is after the Host name in the user request URL.
    # The user request URL looks something like this, 
    # https://<User Request Host>/ContactUs/contact-us.txt#fr.
    # The target language code in the S3 GET request is after the "#" 
    
    user_request_url = unquote(user_request_url) 
    result = user_request_url.split("#") 
    user_request_url = result[0] 
    targetLang = result[1]
    
    # Extract the S3 Object Key from the user requested URL 
    s3Key = str(Path(urlparse(user_request_url).path).relative_to('/'))
    
    # Get the original object from S3 
    s3 = boto3.resource('s3')
    
    # To get the original object from S3,use the supporting_access_point_arn  
    s3Obj = s3.Object(supporting_access_point_arn, s3Key).get() 
    srcText = s3Obj['Body'].read() 
    srcText = srcText.decode('utf-8')
    
    # Translate original text 
    translateClient = boto3.client('translate') 
    response = translateClient.translate_text(
        Text = srcText, 
        SourceLanguageCode='en', 
        TargetLanguageCode=targetLang)
        
    # Write object back to S3 Object Lambda 
    s3client = boto3.client('s3') 
    s3client.write_get_object_response( 
        Body=response['TranslatedText'], 
        RequestRoute=request_route, 
        RequestToken=request_token )
        
    return { 'statusCode': 200 }
  • オブジェクトコンテキストから outputRouteoutputTokenを抽出します。これにより、WriteGetObjectResponseリクエストが配信される場所を定義します。
  • イベントオブジェクトからユーザーが要求した URL を抽出します。
  • S3 オブジェクトキーと S3 オブジェクトキーに追加されたターゲット言語をパースします。
  • S3 GetObject を呼び出して、ソースオブジェクトの生のテキストを取得します。
  • 未加工のテキストを抽出して Amazon 翻訳を呼び出します。
  • WriteGetObjectResponse API を使用して、翻訳された出力を S3 に戻します。

Lambda IAM ロールの設定

Lambda 関数には、WriteGetObjectResponse を使用して S3 Object Lambda アクセスポイントにコールバックするためのアクセス権限が必要です。S3 GetObject と Amazon Translateを呼び出すためのアクセス許可も必要です。Lambda 実行ロールに次の権限を追加します。

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
        { 
            "Sid": "S3ObjectLambdaAccess", 
            "Effect": "Allow", 
            "Action": [ 
                "s3:GetObject", 
                "s3-object-lambda:WriteGetObjectResponse" 
            ], 
            "Resource": [ 
                "<arn of your S3 access point/*>", 
                "<arn of your Object Lambda accesspoint>" 
            ] 
        }, 
        { 
            "Sid": "AmazonTranslateAccess", 
            "Effect": "Allow", 
            "Action": "translate:TranslateText", 
            "Resource": "*" 
        } 
    ] 
}

AWS SAM テンプレートを使用した Lambda のデプロイ

または、AWS SAM テンプレートを使用して IAM ロールで Lambda 関数をデプロイします。Lambda 関数と AWS SAM テンプレートのコードは GitHub からダウンロードできます。

S3 アクセスポイントの作成

  1. S3 コンソールに移動し、一意の名前のバケットを作成します。
  2. S3 コンソールで、[Access Points] を選択し、[Create access point] を選択します。アクセスポイントの名前を入力します。
  3. [Bucket name] に、ステップ 1 で入力した S3 バケット名を入力します。

Create access point

このアクセスポイントは、次の手順で作成する Object Lambda アクセスポイントのサポートするアクセスポイントです。このページのその他の設定はすべてデフォルトのままにします。

S3 アクセスポイントを作成したら、サポートするアクセスポイントを使用して S3 Object Lambda アクセスポイントを作成します。前に作成した Lambda 関数は、サポートされたアクセスポイントを使用して、元の未変換オブジェクトを S3 からダウンロードします。

Object Lambda アクセスポイントの作成

S3 コンソールで、Object Lambda アクセスポイントの設定に移動し、Object Lambda アクセスポイントを作成します。名前を入力します。

Create Object Lambda Access Point

Lambda 関数の設定では、これを先に作成した Lambda 関数に関連付けます。Lambda 関数の$LATESTバージョンを選択し、他のすべての設定をデフォルトのままにします。

Select Lambda function

S3 Object Lambda 設定のその他の設定の使用方法については、製品のドキュメントを参照してください。

動的コンテンツ翻訳のテスト

このセクションでは、Python スクリプトを作成し、S3 GetObject API を 2 回呼び出します。まず、S3 バケットに対して、次にObject Lambda アクセスポイントに対して呼び出しを行います。次に、出力を比較して Object Lambda を使用してコンテンツがどのように変換されるかを確認できます。

  1. 設定したObject Lambda アクセスポイントを使用するS3 バケットにテキストファイルをアップロードします。たとえば、英語のサンプル “Contact Us“ ファイルを S3 にアップロードします。
  2. Object Lambda アクセスポイントを使用するには、[Object Lambda Access Points] の [Properties] タブから ARN を見つけます。
    Object Lambda Access Point
  3. 次の Python スクリプトを含む s3ol_client.pyというローカルファイルを作成します。
    import json
    import boto3
    import sys, getopt
      
    def main(argv):
        
      try:    
        targetLang = sys.argv[1]
        print("TargetLang = ", targetLang)
        
        s3 = boto3.client('s3')
        s3Bucket = "my-s3ol-bucket"
        s3Key = "ContactUs/contact-us.txt"
    
        # Call get_object using the S3 bucket name
        response = s3.get_object(Bucket=s3Bucket,Key=s3Key)
        print("Original Content......\n")
        print(response['Body'].read().decode('utf-8'))
    
        print("\n")
    
        # Call get_object using the S3 Object Lambda access point ARN
        s3Bucket = "arn:aws:s3-object-lambda:us-west-2:123456789012:accesspoint/my-s3ol-access-point"
        s3Key = "ContactUs/contact-us.txt#" + targetLang
        response = s3.get_object(Bucket=s3Bucket,Key=s3Key)
        print("Transformed Content......\n")
        print(response['Body'].read().decode('utf-8'))
    
        return {'Success':200}             
      except:
        print("\n\nUsage: s3ol_client.py <Target Language Code>")
    
    #********** Program Entry Point ***********
    if __name__ == '__main__':
        main(sys.argv[1: ])
  4. コマンドラインからクライアントプログラムを実行し、ターゲット言語コードを引数として渡します。Amazon Translateでサポートされている言語とコードの完全なリストは、こちらにあります。python s3ol_client.py "fr"

出力は以下のようになります。

Example output

最初の出力は、S3 バケット名で GetObject を呼び出すときに取得された元のコンテンツです。2 番目の出力は、Object Lambda アクセスポイントに対して GetObject を呼び出すときに変換されたコンテンツです。コンテンツは、取得中の Lambda 関数によって変換され、ほぼリアルタイムでフランス語に翻訳されます。

まとめ

このブログ記事では、S3 Object Lambda を Amazon Translate で使用して、データ駆動型アプローチを使用して動的コンテンツ翻訳を簡素化する方法について説明しました。ユーザーが指定したデータを引数として使用すると、S3 内のコンテンツを動的に変換し、新しいオブジェクトを生成できます。

クライアントへと返す前に、この新しいオブジェクトのコピーを S3 で作成する必要はありません。また、S3 Object Lambda を使用する場合、同じ名前のオブジェクトが S3 バケットに存在する必要はないことも確認しました。このパターンは、S3 オブジェクトをオンザフライで変換および生成する機能の恩恵を受けることができるいくつかの現実世界のユースケースに対処するために使用できます。

サーバーレスラーニングリソースの詳細については、Serverless Landをご覧ください。

翻訳はソリューションアーキテクト福本が担当しました。原文はこちらです。