AWS Lambda
開発者ガイド

サンプル Amazon Simple Storage Service 関数コード

サンプルコードは以下の言語で利用可能です。

トピック

Node.js 8

以下のコード例では、Amazon S3 イベント入力を受け取り、含まれるメッセージを処理します。ソースバケットのイメージのサイズを変更し、ターゲットバケットに出力を保存します。

例 index.js

// dependencies var async = require('async'); var AWS = require('aws-sdk'); var gm = require('gm') .subClass({ imageMagick: true }); // Enable ImageMagick integration. var util = require('util'); // constants var MAX_WIDTH = 100; var MAX_HEIGHT = 100; // get reference to S3 client var s3 = new AWS.S3(); exports.handler = function(event, context, callback) { // Read options from the event. console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); var srcBucket = event.Records[0].s3.bucket.name; // Object key may have spaces or unicode non-ASCII characters. var srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")); var dstBucket = srcBucket + "resized"; var dstKey = "resized-" + srcKey; // Sanity check: validate that source and destination are different buckets. if (srcBucket == dstBucket) { callback("Source and destination buckets are the same."); return; } // Infer the image type. var typeMatch = srcKey.match(/\.([^.]*)$/); if (!typeMatch) { callback("Could not determine the image type."); return; } var imageType = typeMatch[1]; if (imageType != "jpg" && imageType != "png") { callback('Unsupported image type: ${imageType}'); return; } // Download the image from S3, transform, and upload to a different S3 bucket. async.waterfall([ function download(next) { // Download the image from S3 into a buffer. s3.getObject({ Bucket: srcBucket, Key: srcKey }, next); }, function transform(response, next) { gm(response.Body).size(function(err, size) { // Infer the scaling factor to avoid stretching the image unnaturally. var scalingFactor = Math.min( MAX_WIDTH / size.width, MAX_HEIGHT / size.height ); var width = scalingFactor * size.width; var height = scalingFactor * size.height; // Transform the image buffer in memory. this.resize(width, height) .toBuffer(imageType, function(err, buffer) { if (err) { next(err); } else { next(null, response.ContentType, buffer); } }); }); }, function upload(contentType, data, next) { // Stream the transformed image to a different S3 bucket. s3.putObject({ Bucket: dstBucket, Key: dstKey, Body: data, ContentType: contentType }, next); } ], function (err) { if (err) { console.error( 'Unable to resize ' + srcBucket + '/' + srcKey + ' and upload to ' + dstBucket + '/' + dstKey + ' due to an error: ' + err ); } else { console.log( 'Successfully resized ' + srcBucket + '/' + srcKey + ' and uploaded to ' + dstBucket + '/' + dstKey ); } callback(null, "message"); } ); };

デプロイパッケージは、Lambda 関数のコードと依存関係を含む .zip ファイルです。

デプロイパッケージを作成するには

  1. フォルダ (examplefolder) を作成してから、サブフォルダ (node_modules) を作成します。

  2. Node.js プラットフォームをインストールします。詳細については、Node.js のウェブサイトを参照してください。

  3. 依存関係をインストールします。コード例では、以下のライブラリを使用します。

    • Node.js 内の AWS SDK for JavaScript

    • gm(node.js の GraphicsMagick)

    • 非同期ユーティリティモジュール

    AWS Lambda ランタイムには Node.js に AWS SDK for JavaScript がすでにあるため、他のライブラリをインストールする必要があります。コマンドプロンプトを開き、examplefolder に移動し、npm コマンドを使用して Node.js の一部であるライブラリをインストールします。

    npm install async gm
  4. index.js という名前のファイルにサンプルコードを保存します。

  5. 前述のコードを確認し、以下の点に注意します。

    • 関数は、パラメータとして受信するイベントデータから、ソースバケット名とオブジェクトのキー名を知ることができます。オブジェクトが .jpg の場合、コードではサムネイルが作成され、ターゲットバケットに保存されます。

    • コードでは、ターゲットバケットが存在し、ソースバケット名の後に文字列 resized を連結したものがそのバケット名になっているとします。たとえば、イベントデータで特定されたソースバケットが examplebucket の場合、コードでは examplebucketresized 宛先バケットがあると想定されます。

    • 作成されるサムネイルについて、コードでは、文字列 resized- の後にソースオブジェクトキー名を連結したものをそのキー名として生成します。たとえば、ソースオブジェクトキーが sample.jpg の場合、コードではキー resized-sample.jpg があるサムネイルオブジェクトが作成されます。

  6. ファイルを index.js として examplefolder に保存します。この手順を完了すると、以下のようなフォルダー構造になります。

    index.js /node_modules/gm /node_modules/async
  7. index.js ファイルと node_modules フォルダを CreateThumbnail.zip という名前で ZIP 圧縮します。

Java 8

以下に示すのは、受信する Amazon S3 イベントを読み取り、サムネイルを作成する Java コードの例です。この例では、aws-lambda-java-core ライブラリに用意された RequestHandler インターフェイスを実装しています。したがって、Lambda 関数を作成するときは、クラスをハンドラー(example.S3EventProcessorCreateThumbnail)として指定します。インターフェイスを使用したハンドラーの提供の詳細については、「ハンドラ作成用に事前定義されているインターフェイスの利用 (Java)」を参照してください。

ハンドラーが入力型として使用する S3Event 型は、受信する Amazon S3 イベントから簡単に情報を読み取るためのメソッドを提供する、aws-lambda-java-events ライブラリの定義済みクラスの 1 つです。このハンドラーは出力として文字列を返します。

例 S3EventProcessorCreateThumbnail.java

package example; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URLDecoder; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.imageio.ImageIO; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.S3Event; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.S3Object; public class S3EventProcessorCreateThumbnail implements RequestHandler<S3Event, String> { private static final float MAX_WIDTH = 100; private static final float MAX_HEIGHT = 100; private final String JPG_TYPE = (String) "jpg"; private final String JPG_MIME = (String) "image/jpeg"; private final String PNG_TYPE = (String) "png"; private final String PNG_MIME = (String) "image/png"; public String handleRequest(S3Event s3event, Context context) { try { S3EventNotificationRecord record = s3event.getRecords().get(0); String srcBucket = record.getS3().getBucket().getName(); // Object key may have spaces or unicode non-ASCII characters. String srcKey = record.getS3().getObject().getKey() .replace('+', ' '); srcKey = URLDecoder.decode(srcKey, "UTF-8"); String dstBucket = srcBucket + "resized"; String dstKey = "resized-" + srcKey; // Sanity check: validate that source and destination are different // buckets. if (srcBucket.equals(dstBucket)) { System.out .println("Destination bucket must not match source bucket."); return ""; } // Infer the image type. Matcher matcher = Pattern.compile(".*\\.([^\\.]*)").matcher(srcKey); if (!matcher.matches()) { System.out.println("Unable to infer image type for key " + srcKey); return ""; } String imageType = matcher.group(1); if (!(JPG_TYPE.equals(imageType)) && !(PNG_TYPE.equals(imageType))) { System.out.println("Skipping non-image " + srcKey); return ""; } // Download the image from S3 into a stream AmazonS3 s3Client = new AmazonS3Client(); S3Object s3Object = s3Client.getObject(new GetObjectRequest( srcBucket, srcKey)); InputStream objectData = s3Object.getObjectContent(); // Read the source image BufferedImage srcImage = ImageIO.read(objectData); int srcHeight = srcImage.getHeight(); int srcWidth = srcImage.getWidth(); // Infer the scaling factor to avoid stretching the image // unnaturally float scalingFactor = Math.min(MAX_WIDTH / srcWidth, MAX_HEIGHT / srcHeight); int width = (int) (scalingFactor * srcWidth); int height = (int) (scalingFactor * srcHeight); BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = resizedImage.createGraphics(); // Fill with white before applying semi-transparent (alpha) images g.setPaint(Color.white); g.fillRect(0, 0, width, height); // Simple bilinear resize // If you want higher quality algorithms, check this link: // https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g.drawImage(srcImage, 0, 0, width, height, null); g.dispose(); // Re-encode image to target format ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(resizedImage, imageType, os); InputStream is = new ByteArrayInputStream(os.toByteArray()); // Set Content-Length and Content-Type ObjectMetadata meta = new ObjectMetadata(); meta.setContentLength(os.size()); if (JPG_TYPE.equals(imageType)) { meta.setContentType(JPG_MIME); } if (PNG_TYPE.equals(imageType)) { meta.setContentType(PNG_MIME); } // Uploading to S3 destination bucket System.out.println("Writing to: " + dstBucket + "/" + dstKey); s3Client.putObject(dstBucket, dstKey, is, meta); System.out.println("Successfully resized " + srcBucket + "/" + srcKey + " and uploaded to " + dstBucket + "/" + dstKey); return "Ok"; } catch (IOException e) { throw new RuntimeException(e); } } }

Amazon S3 は Event 呼び出しタイプを使用して Lambda 関数を呼び出します。ここで、AWS Lambda はコードを非同期に実行します。戻り値は重要ではありません。ただし、この場合、戻り値の型の指定を必要とするインターフェイスを実装するため、この例ではハンドラーは戻り値として String を使用します。

Python 3

以下のコード例では、Amazon S3 イベント入力を受け取り、含まれるメッセージを処理します。ソースバケットのイメージのサイズを変更し、ターゲットバケットに出力を保存します。

例 CreateThumbnail.py

from __future__ import print_function import boto3 import os import sys import uuid from PIL import Image import PIL.Image s3_client = boto3.client('s3') def resize_image(image_path, resized_path): with Image.open(image_path) as image: image.thumbnail(tuple(x / 2 for x in image.size)) image.save(resized_path) def handler(event, context): for record in event['Records']: bucket = record['s3']['bucket']['name'] key = record['s3']['object']['key'] download_path = '/tmp/{}{}'.format(uuid.uuid4(), key) upload_path = '/tmp/resized-{}'.format(key) s3_client.download_file(bucket, key, download_path) resize_image(download_path, upload_path) s3_client.upload_file(upload_path, '{}resized'.format(bucket), key)

デプロイパッケージを作成するには

  1. サンプルコードを CreateThumbnail.py という名前のファイルにコピーします。

  2. 仮想環境を作成します。

    virtualenv ~/shrink_venv

    source ~/shrink_venv/bin/activate

  3. 仮想環境にライブラリをインストールします

    pip install Pillow

    pip install boto3

    注記

    AWS Lambda には、Python 向けの AWS SDK (Boto 3) が含まれるため、デプロイパッケージに含める必要はありませんが、ローカルテストのためにオプションで含めることはできます。

  4. lib および lib64 サイトパッケージの内容を .zip ファイルに追加します。

    cd $VIRTUAL_ENV/lib/python3.7/site-packages

    zip -r9 ~/CreateThumbnail.zip .

  5. .zip ファイルに Python コードを追加します。

    cd ~

    zip -g CreateThumbnail.zip CreateThumbnail.py

このページの内容: