Python

[boto3] S3 내 지정한 경로 내의 하위 경로 조회

비번변경 2022. 12. 26. 22:51

개요

aws cli로 s3 ls를 했을 때, 지정한 prefix에 존재하는 subprefix 정보를 boto3을 통해 얻고 싶다.

방법을 정리한다.

 

 

client.list_objects_v2

버킷에 존재하는 객체의 일부 또는 전체(최대 1000개)를 반환한다. 조회할 버킷의 이름(Bucket), 조회할 prefix를 지정해야 한다.

response = client.list_objects(
    Bucket='string',
    Delimiter='string',
    EncodingType='url',
    Marker='string',
    MaxKeys=123,
    Prefix='string',
    RequestPayer='requester',
    ExpectedBucketOwner='string'
)

 

response 예시

{
    'IsTruncated': True|False,
    'Marker': 'string',
    'NextMarker': 'string',
    'Contents': [
        {
            'Key': 'string',
            'LastModified': datetime(2015, 1, 1),
            'ETag': 'string',
            'ChecksumAlgorithm': [
                'CRC32'|'CRC32C'|'SHA1'|'SHA256',
            ],
            'Size': 123,
            'StorageClass': 'STANDARD'|'REDUCED_REDUNDANCY'|'GLACIER'|'STANDARD_IA'|'ONEZONE_IA'|'INTELLIGENT_TIERING'|'DEEP_ARCHIVE'|'OUTPOSTS'|'GLACIER_IR',
            'Owner': {
                'DisplayName': 'string',
                'ID': 'string'
            }
        },
    ],
    'Name': 'string',
    'Prefix': 'string',
    'Delimiter': 'string',
    'MaxKeys': 123,
    'CommonPrefixes': [
        {
            'Prefix': 'string'
        },
    ],
    'EncodingType': 'url'
}

 

조회한 객체의 Prefix는 응답의 CommonPrefixes.Prefix 부분에 해당한다.

 

객체를 조회할 Prefix만 지정하면 해당 Prefix 아래에 존재하는 모든 객체가 나열된다.

S3는 디렉터리, 폴더 개념이 없기 때문에 Prefix를 조회할 때에는 Delimiter 매개변수에 '/' 문자를 전달하여 사용하면 된다.

 

+ list_objects_v2 함수는 list_objects 함수를 대체하는 함수이다.

 

 

소스

import boto3
import botocore

def get_client(aws_access_key_id=None, aws_secret_access_key=None,
               profile_name=None):
    if aws_access_key_id is not None:
        client = boto3.client('s3',
                              aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key)
    elif profile_name is not None:
        session = get_session(profile_name=profile_name)
        client = session.client('s3')
    else:
        client = boto3.client('s3')

    return client


def get_subprefix(Bucket, prefix='', client=get_client()):
    response = client.list_objects(Bucket=Bucket, Prefix=prefix, Delimiter='/')['CommonPrefixes']
    result = [r.get('Prefix') for r in response]
    return result
    
    
if __name__ == '__main__':
    bucket_name = 'test_bucket'
    
    # 최상위 PREFIX
    print(get_subprefix(bucket_name))
    
    # SUB PREFIX
    prefix = 'database/'
    print(get_subprefix(bucket_name, prefix))

 

실행 결과

['database/', 'logs/']
['db=america/']

 

 

참고 문서

https://github.com/boto/boto3/issues/134

https://stackoverflow.com/questions/35803027/retrieving-subfolders-names-in-s3-bucket-from-boto3

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

https://joytk.tistory.com/55