본문 바로가기
AWS

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

by Wave sea 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을 반환

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