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
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 경로를 추가하고 최종적으로 해당 값을 반환하면 사용자는 이미지를 보고 선택할 수 있게 된다.