본문 바로가기

AWS

[AWS] Python에서 S3 bucket 파일 목록 가져오기

문제인식: 실무에서 이미지와 json형태의 Label 데이터를 AWS S3에 저장하고 있는데, 새로운 OCR분석 API를 테스트 하기 위해 S3에 저장된 파일들을  API에 태우는 것이 필요함. 따라서, S3 파일 목록과 S3파일 자체를 불러오는 기술이 필요

문제해결: boto3 라이브러리를 이용. boto3의 client, resource 함수를 비교, 사용해보고, 그 중 적절한 함수를 이용해서, 파일 불러오기

문제해결방법 : 구글링 및 자체 S3 버킷 및 파일에 맞도록 코드 수정

AWS S3에 있는 파일 불러오기

0. 들어가기에 앞서

python에서 AWS s3에 접속하여 버킷(Bucket)과 객체(object)를 다루기 위해서는 일반적으로 boto3라는 라이브러리를 많이 사용한다. 따라서 우선 boto3를 install하고 import하는 과정이 필요하다.

# 터미널 창에
pip install boto3

# python 파일에 dependency import
import boto3

python에서 AWS s3를 다루는 방법을 설명한 여러 블로그, 설명 등을 살펴보면 어떤 경우에는 boto3의 client 함수를 사용하고 또 다른 경우에는 resourece 함수를 사용하는 모습을 볼 수 있다. 다만 이 둘의 차이에 대해서, 어떤 상황에서 어떤 함수를 사용해야 하는지에 대해서는 자세한 설명이 없는 관계로 두 함수의 차이와 사용법에 대해서 설명하고 지나간다.

0.1. boto3.Clinet

Clients는 AWS 서비스의 낮은 수준의 인터페이스를 제공
botocore 라이브러리의 Json serviece description로 만들어짐
실제 AWS service API와 1대1로 mapping됨
모든 AWS service operation이 client를 지원함

import boto3

# s3에 있는 버킷(bucket) 리스트 검색
s3 = boto3.client("s3")
response = s3.list_buckets()

# 버킷 이름 출력
print("Existing buckets : ")
for bucket in response["Buckets"]:
	print(f"{bucket['Name']}")

# 특정 버킷에 있는 객체 리스트 출력
bucket_name = "your-bucket-name"
client = boto3.client('s3')
response = client.list_objects(Bucket = bucket_name)
print(response)

# 특정버킷에 있는 객체 정보 불러오기
bucket_name = "your-bucket-name"
client = boto3.client('s3')
response = client.list_objects(Bucket = bucket_name)

for contents in response.get("Contents"):
	obj_dict = client.get_object(Bucket = bucket_name, Key = content.get('Key')
    print(content.get("Key"), obj_dict.get("LastModified")) # key 값과 최종 수정 일시 출력

0.2. boto3.resource

resource는 client보다 높은 수준의 추상화된 인터페이스를 제공
resource는 객체지향 인터페이스를 제공
모든 resource instance는 Identifiers, Attributes, Actions로 구성됨

# resource instantiate (리소스 인스턴스화)
import boto3
s3 = boto3.resource("s3")

# Identifiers
bucket = s3.Bucket(name = "your-bucket-name")

obj = s3.Object(bucket_name = "your-bucket-name", key = "your-object-name")

# Actions
obj = s3.Object(bucket_name = "your-bucket-name", key = "your-object-name")
# action on S3 object
response = obj.get()

# client의 예제와 같이 key값과 최종 수정 일시 불러오기
bucket_name = 'your-bucket-name'
s3 = boto3.resource('s3')
bucket = s3.Bucket(bucket_name)

for obj in bucket.objects.all():
	print(obj.key, obj.last_modified)

요약하면, resource가 client에 비해서 더 높은 수준의 추상화이다. resource가 boto3를 이용함에 있어서 기본 세부사항을고려하지 않아도 되기 때문에 더 권장된다. resource로 작성된 코드가 client로 작성된 코드보다 더 단순한 경향이 있다.
그러나, resource는 AWS의 일부 서비스에서 사용할 수 없기 때문에, 이 경우 client를 사용할 수 밖에 없다.
따라서 아래의 예제는 최대한 resource를 이용해서 작성한다.

1. S3에 해당 버킷에 파일 있는지 확인

import boto3

s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket(name = 'your-bucket-name')
bucket.Object('your-file-name').key

2. S3에서 파일 불러오기

s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket(name = 'your-bucket-name')
bucket.Object('your-file-name').get()

3. S3에서 특정 버킷 파일 목록 불러오기

# resource로 하는 방법 찾아봐야함

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.ServiceResource.buckets

 

S3 — Boto3 Docs 1.24.75 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

3.1. client로 하는 방법

import os
import boto3

path = 'image-path'
bucket_name = 'your-bucket-name'

s3 = boto3.client("s3")

# 전체 파일 목록 가져오는 함수
def get_all_keys(**args):
	# 전체 파일목록(key) 반환용 list
    keys = []
    
    """ 1000개씩 반환되는 list_objects_v2의 결과 paging 처리를 위한 paginator 선언"""
    page_iterator = s3.get_paginator("list_objects_v2")
    for page in page_iterator.paginate(**args):
    	try:
        	contents = page.get("Contents")
		except KeyError:
			break
		for item in contents:
        	keys.append(item.get("Key"))
	return keys

# 특정 버킷(bucket)의 특정 path하의 파일들만 가져오기
def makeManifest(path):
	entries = get_all_keys(Bucket = bucket_name, Prefix = path)
    for entry in entries:
    	# 이미지만
        if os.path.splitext(entry)[1].lower() in ('.png', '.jpg', '.jpeg'):
        	ref = f"{{'source-ref': 's3://{bucket_name}/{entry}'}}"
            print(ref)

makeManifest(path)

 

# 이후 추가 필요
# 작성 중인 글입니다.

 

※ 참고

 

[AWS] S3 버켓에서 파일 목록 가져 오기(python)

S3의 특정 버켓의 폴더에 업로드된 전체 파일 목록을 가져오는 방법에 대한 기록. - 주 사용 함수: boto3....

blog.naver.com

 

boto3.resource와 boto3.client의 차이

boto3는 워낙 기능이 방대하다 보니 대부분의 경우에는 gist 등에서 예제를 찾아보게 되는데, boto3.resource 를 사용하는 예제도 있고, boto3.client 를 사용하는 예제도 있었다. 둘을 비교해 보자. Client lo

planbs.tistory.com

 

Boto 3: Resource vs Client

AWS' Boto library is used commonly to integrate Python applications with various AWS services. The two most commonly used features of boto3 are Clients and Resources. In this article, we will look into each one of these and explain how they work and when t

www.learnaws.org