Python argparse, S3 folder upload 폴더 업로드
Language/Python

Python argparse, S3 folder upload 폴더 업로드

뉴비뉴 2022. 7. 16.

안녕하세요,
자주 쓰이는 argparse와 S3 folder upload 에 대해 알아보겠습니다.
보통 S3 를 사용하면 folder를 통째로 올리는 경우는 많이 없는 것 같습니다.

예를 간단히 하나 들겠습니다.

차량을 10개 가지고 있다고 가정하겠습니다.
10개의 차량이 한번에 갈 수 있는 곳은 미국과 유럽으로 한정되어 있습니다.

추가적으로 10대의 자동차는 비행기(S3)를 이용해야 합니다.

정리하면 나의 차량(Local) 10대를 비행기(S3)를 탑승해야되는 겁니다.

자 시작해볼까요?

Argparse

https://docs.python.org/ko/3/library/argparse.html

import argparse

if __name__ = '__main__':
    parser = argparse.ArgumentParser(description="if you choose")
    parser.add_argument('--car-brand', required=True, help="")
    parser.add_argument('--car-input-path', required=True, help="")
    parser.add_argument('--car-output-path', required=True, help="")
    
    args = parser.parse_args()
    sell_car(args.car_brand, args.car_input_path, args.car_output_path)

차량 이동하는 날짜는 car input path에 저장하겠습니다.

왜냐하면 차량이 한번만 이동하는게 아니라 이런 일이 반복적으로 들어온 다는 것이죠

로컬에 차량에 대한 정보들은 기본적으로 /date/{2022-01-01}/sell/car 에 있습니다.

우리는 차량에 정보도 뻐지면 안되겠죠?

def sell_car(car_brand, car_input_path, car_output_path):
    if car_brand == "bmw":
        input_path = car_input_path
        output_path = car_output_path
    elif car_brand = "hyundai"
        input_path = car_input_path
        output_path = car_output_path

S3 folder upload

import os
import boto3
import argparse


BUCKET = os.getenv('BUCKET', 'seller')


def upload_dir(profile_name, local_directory, bucket, destination):
    if(False == os.path.isdir(local_directory)):
        return False

    session = boto3.Session(profile_name=profile_name)
    s3_client = session.client('s3')

    for root, dirs, files in os.walk(local_directory):
        for filename in files:
            local_path = os.path.join(root, filename)
            relative_path = os.path.relpath(local_path, local_directory)

            s3_path = f"{destination}/{filename}"

            try:
                print(f"Uploading {s3_path}")
                s3_client.upload_file(local_path, bucket, s3_path)
            except ClientError as e:
                print(e)
                return False

    return True

finally

import os
import boto3
import argparse


BUCKET = os.getenv("BUCKET", "seller-car")
AWS_ACCESS_KEY_ID = ""
AWS_SECRET_ACCESS_KEY = ""

                           # /date/{2022-01-01}/sell/car 
                                            # seller-car
                                                    # /sell/car/mercedes_benz/
             # sell                                 # /sell/car/bmw/
def upload_dir(profile_name, local_directory, bucket, destination):
    if(False == os.path.isdir(local_directory)):
        return False

    session = boto3.Session(profile_name=profile_name)
    s3_client = session.client('s3')

    for root, dirs, files in os.walk(local_directory):
        for filename in files:
            local_path = os.path.join(root, filename)
            relative_path = os.path.relpath(local_path, local_directory)

            s3_path = f"{destination}/{filename}"

            try:
                print(f"Uploading {s3_path}")
                s3_client.upload_file(local_path, bucket, s3_path)
            except ClientError as e:
                print(e)
                return False

    return True


def sell_car(car_brand, car_input_path, car_output_path):
    if car_brand == "bmw":
        input_path = car_input_path
        output_path = car_output_path
        
        upload_dir("default", f"{input_path}", f"{BUCKET}", f"{output_path}")
    elif car_brand == "hyundai":
        input_path = car_input_path
        output_path = car_output_path
        
        upload_dir("default", f"{input_path}", f"{BUCKET}", f"{output_path}")


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="if you choose")
    parser.add_argument('--car-brand', required=True, help="bmw or hyundai")
    parser.add_argument('--car-input-path', required=True, help="/date/2022-01-01/sell/car/hyundai/")
    parser.add_argument('--car-output-path', required=True, help="car/hyundai/")

    args = parser.parse_args()
    sell_car(args.car_brand, args.car_input_path, args.car_output_path)

S3 버킷을 만드는 것은 아주 간단합니다.

하지만 위와 같이 코드를 작성하여 돌렸을 때

An error occurred (AccessDenied) when calling the PutObject operation: Access Denied 에러가 발생합니다. 

이 문제의 경우는 버킷의 객체 소유권 편집에서 ACL 활성화됨으로

변경하면 됩니다. 그리고 변경 사항 저장을 눌러줍시다.

 

아차! 그리고 input_path 에는 경로에 맞게끔 로컬 디렉토리를 만들어줘야 합니다.

 

AWS_ACCESS_KEY_ID = ""
AWS_SECRET_ACCESS_KEY = " 는 AWS IAM 에서 사용자를 만들어주시고, 

거기에 권한 AmazonS3FullAccess 를 추가해주면 됩니다.

좋습니다!

그러면 우리가 원했던 파일 업로드가 아닌 폴더 업로드를 구현할 수 있습니다.

댓글

💲 추천 글