이제 이미지 로컬 저장 -> 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
다음 각 정보를 입력한다.
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 를 참고 하라고 한다.
예시로 이렇게 쓰라고 한다.
더 자세한 내용은 문서 참고 해야할거같다.
# 변경 전
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+웹개발 취업캠프 - 프론트엔드&백엔드> 과정 학습/프로젝트/과제 기록으로 작성되었습니다.
'코딩캠프 > AI 웹개발 취업캠프' 카테고리의 다른 글
[AI 웹개발 취업캠프] 71Day - 프로젝트 22일차 (0) | 2023.10.31 |
---|---|
[AI 웹개발 취업캠프] 70Day - 프로젝트 21일차 (0) | 2023.10.30 |
[AI 웹개발 취업캠프] 68Day - 프로젝트 19일차 (1) | 2023.10.26 |
[AI 웹개발 취업캠프] 67Day - 프로젝트 18일차 (0) | 2023.10.25 |
[AI 웹개발 취업캠프] 66Day - 프로젝트 17일차 (0) | 2023.10.24 |