코딩캠프/AI 웹개발 취업캠프

[AI 웹개발 취업캠프] 69Day - 프로젝트 20일차

고랑E 2023. 10. 27. 23:29
728x90

이제 이미지 로컬 저장 -> s3 저장으로 바꿔보자

어제 물어본 내용

오늘 회의때 해제 해줬다고 확인해 달라고 한다,

그래서 시작!!

 

AWS S3 세팅

IAM 계정으로 로그인

 

로그인 후 화면

 

S3로 들어간다.

 

버킷 만들기

일반 구성

버킷 이름을 pid-bucket 으로 해주고 지역을 서울로 한다.

 

객체 소유권

ACL 비활성화

 

이 버킷의 퍼블릭 액세스 차단 설정

 

일단은 생성할때 차단으로 설정한다.. 어짜피 수정해야됨

 

버킷 버전 관리

 

비활성화

 

태그

다음으로 패스

 

기본 암호화

Amazon S3 관리형 키(SSE-S3)

 

고급 설정

객체 잠금 - 비활성화

 

응 안돼!~

그냥 내 aws 계정으로 테스트 버킷을 생성했다.

버킷 이름만 pid-bucket-test 로 해서 나머지는 동일하게 생성 했다.

 

사용자 그룹 생성

우측 이름 > 보안 자격 증명 > 액세스 관리 > 사용자 그룹에 가준다.

 

그룹 생성

원하는 사용자 그룹 이름으로 정한다 Pid-S3FullAccess 로 하겠다.

 

권한 정책 연결 에서 s3 를 검색해보면 AmazonS3FullAccess 가 나온다.

체크를 해주고 그룹 생성을 한다.

 

생성 완료

 

사용자 생성

왼쪽 패널에서 사용자로 들어간다.

 

 

그 후 사용자 생성

 

사용자 이름 pid_s3_test 로 해준다.

 

권한 설정에서

그룹에 사용자 추가, 사용자 그룹에서 방금 만든 Pid-S3FullAccess 그룹을 체크 하고 넘어간다.

 

검토 및 생성에서는 진짜 검토를 해준다 ㅋㅋㅋ

 

생성완료

 

엑세스 키 및 시크릿 키 발급

pid_s3_test 를 누르고 들어가면 아래와 같이 뜬다.

 

액세스 키1에서 액세스 키 만들기 를 눌러준다.

 

Command Line Interface(CLI) 를 체크하고 아래 동의 체크에도 체크 후 다음으로 넘어간다.

 

설명 태그 설정은 해도 되구 안해도 된다

나는 pid-s3-key 로 설정하고 넘어가겠다~

 

다음 화면에서 키들이 나온다.

꼭 csv파일을 다운받고, 키들을 확인해보자

 

생성 완료

 

액세스(퍼블릭) 허용

S3 버킷화면에 온다 > 만들었던 버킷에 들어간다.

 

권한에 들어간다.

 

퍼블릭 액세스 차단(버킷 설정) 에서 비활성화 해줘야한다.

편집을 눌러준다.

모든 체크를 풀어주고 저장을 한다.

 

확인을 입력해주고 확인 버튼을 누른다.

 

그래도 아직

버킷 및 객체가 퍼블릭이 아님

으로 표시된다.

 

여기서 좀 내려보면 버킷 정책이 보인다.

 

다음 화면이 나오는데

정책 생성기를 눌러준다.

 

새 창이 열리면서 입력 칸들이 나온다.

https://awspolicygen.s3.amazonaws.com/policygen.html

 

AWS Policy Generator

Click below to edit. To save the policy, copy the text below to a text editor. Changes made below will not be reflected in the policy generator tool.

awspolicygen.s3.amazonaws.com

 

다음 각 정보를 입력한다.

Select Type of Policy: S3 Bucket Policy

Effect: Allow Principal: *

Actions: GetObject, PutObject

Amazon Resource Name (ARN): 해당 버킷 ARN 입력

 

액션 부분은

아래 사진처럼 찾아서 체크해줘야 한다.

 

Amazon Resource Name (ARN) 는 버킷 화면에서 복사할 수 있다.

 

모든 부분 입력 후 Add Statement 를 눌러준다.

그럼 아래 쪽에 입력했던 정보가 표시되면서 Generate Policy 버튼이 생긴다.

 

버튼을 누르면 아래와 같이 복사 할수 있는 JSON 이 생성된다.

 

리소스(Resource) 부분 끝에 /* 을 추가한다.

 

수정 해주고 복사 하고 버킷 페이지로 돌아온다.

정책 입력란에 붙여넣기하고 저장한다.

{
  "Id": "Policy1698412874361",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1698412832804",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::pid-bucket-test/*",
      "Principal": "*"
    }
  ]
}

 

그러고 상단을 보면 퍼블릭으로 바뀌었다.

바뀌지 않았을경우 한번 새로고침을 해본다.

 

이제 키들을 .env에 넣고 코드로 넘어가보자~

 

 


Python

 

AWS S3에 이미지를 업로드하려면 bogo3 라는 패키지를 설치해야한다.

pip install boto3

 

.env

아래 처럼 아까 csv 또는 메모해둔 키들을 입력해준다.

S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
BUCKET_NAME=pid-bucket-tes
REGION_NAME=ap-northeast-2

 

main.py

# 상단에 boto3를 임포트해준다.

import boto3
# load_dotenv('.env') 밑쪽에 아래 코드를 입력해준다.

S3_ACCESS_KEY_ID=os.environ["S3_ACCESS_KEY_ID"]
S3_SECRET_ACCESS_KEY=os.environ["S3_SECRET_ACCESS_KEY"]
BUCKET_NAME=os.environ["BUCKET_NAME"]
REGION_NAME=os.environ["REGION_NAME"]
def upload_to_s3(file_path, s3_file_name):
    s3 = boto3.client('s3',
                    aws_access_key_id = S3_ACCESS_KEY_ID,
                    aws_secret_access_key = S3_SECRET_ACCESS_KEY,
                    region_name = REGION_NAME)

    s3.upload_file(str(file_path), BUCKET_NAME, s3_file_name, ExtraArgs={'ContentType': 'image/jpeg'})
    print("업로드 성공")
    s3_url = f"https://{BUCKET_NAME}.s3.{REGION_NAME}.amazonaws.com/{s3_file_name}"
    return s3_url
# 지난번 이후로 아래 코드 2줄을 입력한다.
# s3_file_name = 'images/' + file.filename
# upload_to_s3(file_path, BUCKET_NAME, s3_file_name)

@app.put("/users/{userId}/img")
async def update_user_image(userId: int, file: UploadFile, db: Session = Depends(get_db)):
    file_path = Path.cwd()/'images'/file.filename
    content = await file.read()
    file_path.parent.mkdir(parents=True, exist_ok=True)
    with open(file_path, 'wb') as fs:
        fs.write(content)

    s3_file_name = 'images/' + file.filename
    s3_url = upload_to_s3(file_path, BUCKET_NAME, s3_file_name)
    print('s3_url: ', s3_url)

    user_image(db, user_id = userId, image = file.filename)
    return JSONResponse(content={"message": "프로필 이미지가 수정되었습니다."}, status_code=200)

 

이렇게 입력해주고 파일 업로드 테스트를 해보면

이제 디비에 저장해보자

다음 줄을 프린트 밑에 추가

file.filename = s3_url

 

crud.py

# 변경 전 코드
user.image = './images/' + image

# 변경 후 코드
user.image = image

 

로 수정 후 버킷 객체에서 새롭게 테스트 하기 위해 삭제를 해주고 테스트 해보자

잘 들어갔다 ㅎㅎ

 

이제 로컬에 저장하는 코드를 제거해보자

@app.put("/users/{userId}/img")
async def update_user_image(userId: int, file: UploadFile, db: Session = Depends(get_db)):
    file_path = await file.read()
    
    s3_file_name = 'images/' + file.filename
    s3_url = upload_to_s3(file_path, s3_file_name)
    file.filename = s3_url

    user_image(db, user_id = userId, image = file.filename)
    return JSONResponse(content={"message": "프로필 이미지가 수정되었습니다."}, status_code=200)

로 변경하고 실행해보자

500 에러와 다음과 같은 에러 내용이 발생한다.

ValueError: stat: path too long for Windows

path 길이가 너무 길다는 내용이다.. ?? ㅎ

 

서칭을 하던 도중

PutObject 를 참고 하라고 한다.

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/put_object.html#

 

put_object - Boto3 1.28.72 documentation

Previous put_bucket_website

boto3.amazonaws.com

예시로 이렇게 쓰라고 한다.

더 자세한 내용은 문서 참고 해야할거같다.

# 변경 전
s3.upload_file(str(file_path), BUCKET_NAME, s3_file_name, ExtraArgs={'ContentType': 'image/jpeg'})

# 변경 후
s3.put_object(Body=file_path, Bucket=BUCKET_NAME, Key=s3_file_name)

로 변경 후 테스트

 

성공~

 

 

 

본 후기는 정보통신산업진흥원(NIPA)에서 주관하는 <AI 서비스완성! AI+웹개발 취업캠프 - 프론트엔드&백엔드> 과정 학습/프로젝트/과제 기록으로 작성되었습니다.