본문 바로가기
API/AWS API

AWS - S3 사진 업로드 API, boto3

by 하니__ 2024. 5. 28.

 

 

API 설정

 

경로는 /upload

HTTP 메소드는 

CRUD중 Create에 해당하는

POST 설정

 

사진의 데이터는 아래와 같이

form-data에서 밸류에서 선택

사진과 함께 텍스트가 들어간다면 

마찬가지로 키의 컨텐츠라고 입력, 텍스트 선택,

밸류에 메세지를 입력하자

 

app.py 설정

 

설정하기에 앞서

 

라이브러리 하나를 설치하자

파이썬코드로 AWS 기능들을 사용할 수 있게 해주는 

라이브러리인 boto3

 

 

pip install boto3

 

 

 

 

app.py 설정
from flask import Flask
from flask_restful import Api

from resources.image import FileUploadResource

app = Flask(__name__)


api = Api(app)

# 경로와 리소스 연결
api.add_resource( FileUploadResource ,'/upload')

if __name__ == '__main__':
    app.run()

 

 

간단하게 테스트 먼저 하자

 

image.py 설정
from flask import request
from flask_restful import Resource

class FileUploadResource(Resource) :
    
    def post(self) :
        return { "msg" : "hello"}

 

 

로컬도 서버에서도 정상적으로 작동 한다

 

이제 다시 정상적으로 업로드 하기 위해 진행하자

 

 

일단 파일이 존재하는지부터 확인하고

if 'photo' not in request.files :
    return{"result" : "fail",
           "error" : "파일을 업로드 하세요"} , 400
if 'content' not in request.form :
    return{"result" : "fail",
           "error" : "내용을 작성 하세요"} , 400

 

 

 

있는게 확인 됐으니

file = request.files['photo']

if 'image' not in file.content_type :
    return{"result" : "fail",
           "error" : "이미지 파일만 업로드 가능합니다."}, 400

content = request.form['content']
print(file)
print(content)

current_time = datetime.now()
print(current_time)

 

리퀘스트의 files 에서 사진을 가져오고

 

가져온 파일이 이미지 파일이 맞는지 확인후

이미지 파일이 아니라면 에러메세지와 함께 리턴한다

 

리퀘스트의 form 에서 텍스트를 가져오자

 

그리고 파일을 S3에 업로드해야 하는데
여러 사람이 업로드를 할텐데

각자의 파일명이 중복, 변환될 가능성이 있으니
유니크한 파일명으로 변환시킨 후 업로드 한다
보통은 올리는 유저의 아이디 + 업로드 시간 등으로 한다

해서 현재 시간을 보니 : 콜론이 있어 이는 파일명으로 사용 할 수 없다 그래서

아래와 같이 replace를 이용하여 바꿔주자

print(current_time.isoformat().replace(':', '_')+'.jpg')

 

이제 이 이름을 파일이름으로 설정한뒤 확인해보자

file_name = current_time.isoformat().replace(':', '_')+'.jpg'
print(file_name)

file.filename = file_name
print(file)

 

 

파일이름이 

변환 된것을 확인 할 수 있다

 

여기서 파일 확장자에 .jpg로 지정해 주었는데

사용자가 올린 파일 확장자 그대로 사용하고 싶다면

+ file.content_type.split('/')[-1]

+ .jpg 대신 이걸 써넣으면

파일의 형식이 image/jpg

image/png 이런식으로 나오는것을

/로 스플릿하여 마지막에 있는것을 사용하게끔 하여

 

jpg 라면 jpg

png 라면 png를

사용 할 수 있게 할 수 있다

 

이제 위에서 설치한 boto3를 사용하자

 

client = boto3.client('s3', 
                     aws_access_key_id = Config.AWS_ACCESS_KEY,
                     aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY)

 

여기에 전부 적을 수 없으니

 

config.py를 만들어 아래와 같이 입력후에 위처럼 작성하자

class Config :
    AWS_ACCESS_KEY = '액세스 키'
    AWS_SECRET_ACCESS_KEY = '액세스 시크릿 키'

 

 

 

 

try:
    client.upload_fileobj(file,
                          Config.S3_BUCKET,
                          file_name,
                          ExtraArgs = {"ACL":"public-read",
                                       "ContentType": file.content_type})

 

그리고 위에서 만든 클라이언트의 upload_fileobj( )를 입력하는데

 

첫번째 파라미터에는 위에서 file이라는 이름의 변수로 저장한 파일을,

두번째 파라미터에는 S3 버킷 주소

세번째 파라미터에는 유니크하게 변경한 파일이름

네번째 파라미터에는 ExtraArgs는

Boto3에서 S3 관련 작업을 수행할 때 추가적인 매개변수를 지정하는 데 사용되는데

 

ACL (Access Control List)은 업로드된 파일의 접근 권한을 설정한다

이때 퍼블릭 리드는 모든 사용자가 읽기 가능 이며

 

ContentType 은 업로드 된 파일의 타입형식을 설정한다

여기서는 file.content_type을 선택해 따로 지정하는 것이 아니라

파일의 실제 타입을 입력되게 한다

 

그리고 위에서 지나간 S3버킷 주소 또한

공개할 이유가 없기에

config 파일에 아래와 같이 추가로 작성해준다

 

    S3_BUCKET = '버킷 주소'

 

 

 

그리고 예외상황과 정상결과의 리턴을 적어주고

 

except Exception as e:
    return{"error": str(e)}, 500


return { "result" : "success",
        "url" : Config.S3_URL + file_name }

 

 

url부분은 config에 아래와 같이 적어준다

 

    S3_URL = 'https://버킷주소.s3.ap-northeast-2.amazonaws.com/'

 

 

 

그리고 실행하면

 

이렇게 링크가 나오게 되고

뒷부분 파일명부분에도 시간으로 찍히는게 확인이 가능하고

 

링크를 확인해보면

 

 

 

 

정상적으로 업로드 된것을 확인 할 수 있다

 

 

 

'API > AWS API' 카테고리의 다른 글

AWS - Translate API 사용하기  (0) 2024.05.30
AWS - 객체 감지 API  (0) 2024.05.28