본문 바로가기
AWS

AWS Lambda 개발②) S3 버켓에 새로운 txt 파일 업로드하기

by code_yull 2021. 8. 24.

지난 글에서는 S3 트리거를 통해 업로드된 오브젝트 정보를 가져오는 글을 썼었다.

그렇다면 이번 글에서는 가져온 오브젝트 정보를 가지고, 또다른 S3 버켓에 람다를 활용하여 파일을 업로드하는 방법을 써보려고 한다.

 

import json
import urllib.parse
import boto3

s3 = boto3.client('s3')


def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    
    response = s3.get_object(Bucket=bucket, Key=key)
    originaltext = response['Body'].read().decode('utf-8')

우선 지난 글에서 작성했던 코드이다.

이 코드에서 가져온 originaltext라는 변수를 가지고 코드를 이어서 작성해보자.

 

이번 글에서는 originaltext 변수에 "hello world!" 라는 문자열을 붙인 새로운 문자열을 가지고 텍스트 파일을 작성할 것이다.

그러면 먼저 originaltext 변수에 "hello world!"를 더한 새로운 문자열을 변수에 저장해주어야 한다.

 

newtext = originaltext + "\nhello world!"

 

그리고 텍스트 파일을 작성하기 위해서 utf-8 인코딩을 실행해주어야 한다.

지난 글에서 txt파일의 내용을 utf-8 디코딩을 통해 string 상태의 변수로 가져왔으니, txt 파일을 새로 작성하기 위해서는 utf-8 인코딩을 해주어야 한다.

encoded_text = newtext.encode("utf-8")

 

그러면 이제 txt 파일에 작성할 내용은 준비되었다.

남은 것은 저장할 버킷의 이름과 디렉토리, 파일의 이름을 정해서 해당 버킷에 put_object 해주면 된다.

 

s3 = boto3.resource("s3")

bucket_name = "receive-bucket"
file_name =  "new.txt"
s3_path = "/"+ file_name
    
s3.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_text)

이렇게 하면 encoded_text를 내용으로 하는 new.txt 파일을 receive-bucket의 /디렉토리 안에 업로드할 수 있다.

 

그래서 지난 시간에 작성한 코드와 합쳐보면

import json
import urllib.parse
import boto3

s3 = boto3.client('s3')


def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    
    response = s3.get_object(Bucket=bucket, Key=key)
    originaltext = response['Body'].read().decode('utf-8')
    newtext = originaltext + "\nhello world!"
    encoded_text = newtext.encode("utf-8")
    
    s3 = boto3.resource("s3")

    bucket_name = "receive-bucket"
    file_name =  "new.txt"
    s3_path = "/"+ file_name
    
    s3.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_text)

이렇게 정리될 수 있다.

 

참고로 위 코드에서 s3라는 변수가 두 번 쓰였는데, 윗부분에서 쓰인 s3는 람다를 트리거시킨 이벤트가 발생한 버킷의 정보를 담고 있는 것이고,

아래부분에서 쓰인 s3는 s3에 파일을 업로드하기 위해서 가져온 s3라는 전체 서비스를 뜻하는 것으로 헷갈리면 안된다.

aws의 boto3에 관한 공식 문서에서 자세한 설명을 살펴볼 수 있으니, 더 궁금한 사항이 있다면 공식문서를 살펴보자.

-client에 대한 부분

 

S3 — Boto3 Docs 1.18.26 documentation

A dictionary with two elements: url and fields. Url is the url to post to. Fields is a dictionary filled with the form fields and respective values to use when submitting the post. For example: {'url': 'https://mybucket.s3.amazonaws.com 'fields': {'acl': '

boto3.amazonaws.com

-resource에 대한 부분 

 

Resources — Boto3 Docs 1.18.27 documentation

Overview Resources represent an object-oriented interface to Amazon Web Services (AWS). They provide a higher-level abstraction than the raw, low-level calls made by service clients. To use resources, you invoke the resource() method of a Session and pass

boto3.amazonaws.com

 

그래서 코드를 좀 더 깔끔하게 정리해보자면 아래와 같다.

import json
import urllib.parse
import boto3

s3_trigger = boto3.client('s3')
s3_send = boto3.resource('s3')


def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    
    response = s3_trigger.get_object(Bucket=bucket, Key=key)
    originaltext = response['Body'].read().decode('utf-8')
    newtext = originaltext + "\nhello world!"
    encoded_text = newtext.encode("utf-8")

    bucket_name = "receive-bucket"
    file_name =  "new.txt"
    s3_path = "/"+ file_name
    
    s3_send.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_text)

해당 코드를 바탕으로 파일 이름을 트리거 이벤트에서 가져오거나, 디렉토리를 날짜를 활용하여 자동 생성해주는 등 다양한 활용이 가능하다.

댓글