본문 바로가기
AWS

AWS 이미지 저장을 위한 S3 버킷 만들고 Flask로 저장해보기

by leopard4 2023. 1. 12.

사진을 누구나 볼수있게 공개하겠다는것

 

 

서울에 만들었다
사진을 두개 올렸다.

 

올리는방법

 

기본적인 flask 구성

 

aws_access_key_id= Config.ACCESS_KEY
aws_secret_access_key= Config.SECRET_ACCESS
Config.BUCKET_NAME
Config.S3_LOCATION

부분은 보안을위해 Config.py파일에 별도의 변수로 셋팅해서 호출한다.

 

 

아래 코드는 image.py의 모습

from flask import request # 클라이언트가 보낸 데이터를 받기 위한 라이브러리
from flask_restful import Resource # API를 만들기 위한 라이브러리
from mysql.connector import Error # DB에 연결할 때, 에러가 발생할 수 있으므로, 에러처리를 위한 라이브러리
from flask_jwt_extended import jwt_required, get_jwt_identity
from config import Config # JWT를 사용하기 위한 라이브러리
from mysql_connection import get_connection # DB에 연결하기 위한 함수
from datetime import datetime # 현재 시간을 가져오기 위한 라이브러리
import boto3 # AWS S3에 파일을 업로드하기 위한 라이브러리


class FileUploadResource(Resource) :

    def post(self) :
        
        # 1. 클라이언트가 보낸 데이터를 받는다.
        # request.files : 클라이언트가 보낸 파일 데이터
        # request.form : 클라이언트가 보낸 폼 데이터
        
        if 'photo' not in request.files :
            return {'message' : 'No file'}, 400

        file = request.files['photo']
      
        # 클라이언트가 보낸 파일의 파일명을 
        # 변경시켜서 S3에 올려야, 유니크하게 
        # 파일을 관리할 수 있다.
        
        # 파일명을 유니크하게 만드는 방법
        current_time = datetime.now()  # datetime.now().strftime('%Y%m%d%H%M%S%f') # 시간을 문자열로 변경
        new_file_name = current_time.isoformat().replace(':', '').replace('_', '')+".jpg" # 이런방법도 있음

        print(new_file_name)

        # 파일명을, 유니크한 이름으로 변경한다.
        # 클라이언트가 보낸 파일명을 변경한다.
        
        file.filename = new_file_name

        # s3에 파일을 업로드한다.
        # s3에 파일 업로드 하는 라이브러리가 필요하다.
        # 따라서, pip install boto3 라이브러리를 이용해서 
        # 업로드한다.

        # AWS S3에 접속한다.
        client = boto3.client( 's3' ,
            aws_access_key_id= Config.ACCESS_KEY ,
            aws_secret_access_key= Config.SECRET_ACCESS )
        
        try : 
            client.upload_fileobj( file , # 파일을 업로드한다.
                Config.BUCKET_NAME , 
                new_file_name, 
                ExtraArgs={'ACL':'public-read', 'ContentType' : file.content_type})  # ExtraArgs={'ACL':'public-read'} : 파일을 업로드할 때, 권한을 설정한다.
            
        except Error as e :
            return {'error' : str(e)}, 500

        
        return {'result' : 'success',
                'imgUrl' : Config.S3_LOCATION + new_file_name }, 200

작성이 다 되었으면 app.py 파일로 이동해서 연결한다.

from flask import Flask 
from flask_restful import Api
from flask_jwt_extended import JWTManager

from config import Config
from resource.image import FileUploadResource 

app = Flask(__name__) 

app.config.from_object(Config) 

jwt = JWTManager(app)

api = Api(app) 

# 로그아웃된 토큰으로 요청하는 경우 처리하는 코드작성.
@jwt.token_in_blocklist_loader # 토큰이 만료되었는지 확인하는 함수를 등록한다.
def check_if_token_is_revoked(jwt_header, jwt_payload): # 토큰이 만료되었는지 확인하는 함수
    jti = jwt_payload['jti'] # jti는 JWT 토큰의 고유 식별자
    return jti in jwt_blocklist 

api.add_resource(FileUploadResource, '/upload')

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

 

vscode cmd 에서 가상환경으로 이동 

flask run 으로 서버를 실행하고

포스트맨으로 돌려본다.

결과로 url을 반환

눌러보면 해당 이미지가 나온다.