ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [FastAPI] AWS S3를 활용한 이미지 저장
    프로젝트/당일 2024. 6. 1. 10:15

    AWS S3를 활용한 이미지 저장 왜 궁금했을까❓

    당일 서비스의 경우 사용자가 입력한 일기를 대표하는 이미지를 생성하여 선택할 수 있게 한다. 이미지를 생성한다면 서버에 보관을 했다가 사용자가 필요할 때 사용할 수 있도록 해야한다. 그래서 이미지를 저장하기 위해 AWS S3를 사용하기로 결정했다.

     

    AWS S3를 사용해야 하는 이유?

    • S3는 데이터 저장 공간이 무제한이라는 점에서 확장성이 매우 우수
    • S3는 여러 Region에 데이터를 저장하고 있기 때문에 데이터 손실이 일어날 확률이 거의 제로
    • 사용하는 만큼 비용을 지불하기 때문에 프로젝트성이 강한 당일 서비스에 적합
    • S3에서 다양한 데이터 암호화 방식을 제공
    위 이유 외에도 다양한 장점이 많아서 AWS S3를 당일 서비스에 적용시켜 보려고 한다.

     

    FastAPI와 AWS S3 이미지 저장

    1. 버킷 만들기

    2. 버킷 엑세스 권한 설정

    • S3에 있는 이미지를 사용해야 하기 때문에 외부에 공개해야 하므로 체크 해제
    • 이후, 버킷 만들기 클릭

    3. 퍼블릭 정책 생성

    • 버킷 클릭 후, 권한 탭 클릭
    • 버킷 정책 편집
    • 정책 생성기를 통해서 프로젝트에 맞는 정책 설정
    {
    	"Version": "2012-10-17",
    	"Id": "Policy1714090463840",
    	"Statement": [
    		{
    			"Sid": "Stmt1714090460253",
    			"Effect": "Allow",
    			"Principal": "*",
    			"Action": "s3:GetObject",
    			"Resource": "arn:aws:s3:::ssafy-today/*"
    		}
    	]
    }

     

    4. IAM 설정

    • IAM 검색 후, 사용자 생성 (엑세스 키는 추후 FastAPI에서 사용해야 하므로 따로 저장)
    • 사용자 클릭 후, 권한 추가
    • 직접 정책 연결 선택 후, S3 Full Access 선택

     

    5. FastAPI 연결

    • python에서 AWS S3를 사용하기 위해서는 boto3라는 aws sdk를 사용
    pip install boto3
    • 우선, boto3를 설치한다.
    def connect_s3():
        print("=================== S3 connect start ===================")
        s3 = boto3.client(
            "s3",
            aws_access_key_id=os.getenv("AWS_S3_ACCESS_KEY"),
            aws_secret_access_key=os.getenv("AWS_S3_PRIVATE_KEY")
        )
        app.utils.global_vars.s3 = s3
        print("=================== S3 connect start ===================")
    • 4번 과정에서 저장해놨던 access_key와 private_key를 활용하여 S3 클라이언트와 연결
    # 이미지 저장
    for image in images:
        # 경로 및 파일명 지정
        file_name = f"{str(uuid.uuid4())}.jpg"
        s3_key = f"temp/{file_name}"
    
        # Convert PIL Image to JPG
        img_byte_arr = io.BytesIO()
        image.save(img_byte_arr, format='JPEG')
        img_byte_arr.seek(0)
            
        # S3 Image Upload
        try:
            s3.upload_fileobj(img_byte_arr, os.getenv("AWS_S3_BUCKET"), s3_key)
            images_url.append(os.getenv("AWS_S3_URL") + s3_key)
        except Exception as e:
            raise HTTPException(status_code = 500, detail=f"S3 upload failed: {str(e)}")
        return images_url
    • SDXL을 통해서 생성한 4가지 화풍의 이미지에 UID를 부여하고 SDXL을 통해서 추출한 이미지는 PIL 파일이므로 JPG로 변환 과정이 필요하다.
    • upload_fileobj(이미지 파일, 버킷 이름, s3 키 값)을 이용해서 S3에 저장한다.
    • 이후, images_url에 저장된 S3 경로를 추가하고 최종적으로 해당 값을 반환하면 사용자는 이미지를 보고 선택할 수 있게 된다.
Designed by Tistory.