AWS Lambda
개발자 가이드

샘플 Amazon Simple Storage Service 함수 코드

샘플 코드는 다음 언어로 제공됩니다.

Node.js 8

다음은 Amazon S3 이벤트 입력을 수신하고 이벤트에 포함된 메시지를 처리하는 예제 코드입니다. 이 코드는 소스 버킷의 이미지 크기를 변경하고 출력을 대상 버킷에 저장합니다.

예 index.js

var async = require('async'); var AWS = require('aws-sdk'); var gm = require('gm') .subClass({ imageMagick: true }); // Enable ImageMagick integration. var util = require('util'); var MAX_WIDTH = 100; var MAX_HEIGHT = 100; 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로 작성된 JavaScript용 AWS SDK

    • gm, GraphicsMagick(node.js용)

    • 비동기 유틸리티 모듈

    AWS Lambda 런타임에는 Node.js에 이미 JavaScript용 AWS SDK가 있으므로 다른 라이브러리만 설치하면 됩니다. 명령 프롬프트를 열고 examplefolder로 이동한 후 Node.js의 일부인 npm 명령을 사용하여 라이브러리를 설치합니다.

    $ npm install async gm
  4. 샘플 코드를 index.js 파일에 저장합니다.

  5. 앞의 코드를 검토하고 다음 사항을 확인합니다.

    • 이 함수는 파라미터로 받은 이벤트 데이터에서 원본 버킷 이름과 객체 키 이름을 알고 있습니다. 객체가 .jpg인 경우, 코드는 썸네일을 만들고 대상 버킷에 저장합니다.

    • 이 코드는 대상 버킷이 존재하고 해당 이름이 원본 버킷 이름과 resized 문자열이 이어진 것이라고 가정합니다. 예를 들어 이벤트 데이터에서 식별된 원본 버킷이 examplebucket인 경우 코드는 사용자에게 examplebucketresized 대상 버킷이 있다고 가정합니다.

    • 생성하는 썸네일의 경우 코드는 resized- 문자열과 소스 객체 키 이름이 연결된 키 이름을 가져옵니다. 예를 들어 소스 객체 키가 sample.jpg인 경우 코드는 키가 resized-sample.jpg인 썸네일 객체를 만듭니다.

  6. 파일을 index.jsexamplefolder로 저장합니다. 이 단계를 완료한 후에는 다음과 같은 폴더 구조를 갖게 됩니다.

    index.js /node_modules/gm /node_modules/async
  7. index.js 파일과 node_modules 폴더를 CreateThumbnail.zip으로 압축합니다.

Java 8

다음은 수신하는 Amazon S3 이벤트를 읽고 썸네일을 생성하는 Java 코드의 예입니다. 이는 aws-lambda-java-core 라이브러리에 제공된 RequestHandler 인터페이스를 구현합니다. 따라서 Lambda 함수를 만들 때 클래스를 핸들러(즉, example.S3EventProcessorCreateThumbnail)로 지정합니다. 인터페이스를 사용하여 핸들러를 제공하는 방법에 대한 자세한 내용은 핸들러를 생성하기 위해 사전 정의된 인터페이스 활용(Java) 단원을 참조하십시오.

핸들러가 입력 유형으로 사용하는 S3Event 유형은 수신하는 Amazon S3 이벤트에서 정보를 쉽게 읽을 수 있는 방법을 제공하는 aws-lambda-java-events 라이브러리의 사전 정의된 클래스 중 하나입니다. 핸들러는 문자열을 출력으로 반환합니다.

예 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 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을 반환 유형으로 사용합니다.

종속성

  • aws-lambda-java-core

  • aws-lambda-java-events

  • aws-java-sdk-s3

Lambda 라이브러리 종속성으로 코드를 빌드하여 배포 패키지를 만듭니다. 지침은 AWS Lambda 배포 패키지(Java) 단원을 참조하십시오.

Python 3

다음은 Amazon S3 이벤트 입력을 수신하고 이벤트에 포함된 메시지를 처리하는 예제 코드입니다. 이 코드는 소스 버킷의 이미지 크기를 변경하고 출력을 대상 버킷에 저장합니다.

예 CreateThumbnail.py

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

  4. liblib64 사이트 패키지 콘텐츠를 .zip 파일에 추가합니다.

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

    $ zip -r ~/CreateThumbnail.zip .

  5. python 코드를 .zip 파일에 추가합니다.

    $ cd ~

    $ zip -g CreateThumbnail.zip CreateThumbnail.py

이 페이지에서: