Restful API

[Restful API] 이미지 S3에 업로드하는 API 만들기, boto3

건휘맨 2024. 5. 28. 16:46

포스트맨에서 API 설계부터 시작

경로 설정해주고 Body 에서 form-data

키값을 입력해주고 파일로 지정해서 밸류에 이미지를 업로드

 

Visual Studio Code를 실행해 코드를 작성하기 전에

boto3 를 설치하자 !

boto3 => 파이썬 코드로 aws의 여러 서비스들을 사용할 수 있도록
                aws가 만들어준 라이브러리

pip install boto3

 

설치가 완료되면 코드 작성

1. 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()

 

2. image.py

from flask import request
from flask_restful import Resource

from datetime import datetime

import boto3

from config import Config

class FileUploadResource(Resource):
    
    def post(self):

        # 1. 클라이언트로부터 데이터를 받아온다.
        #    파일은 request.files 안에 있고
        #    텍스트는 request.form 안에 있다.
        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

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

        # 파일을 S3에 업로드해야 하는데
        # 먼저 파일명은 유니크해야 한다.
        # 따라서 유니크한 파일명으로 바꿔서 업로드한다.
        
        # 현재 시간과 유저 아이디 등을 조합해서 만든다.
        current_time = datetime.now()
        file_name = current_time.isoformat().replace(':', '_') + '.' + file.content_type.split('/')[-1]

        print(file_name)

        # 유저가 업로드한 파일명을 내가 만든 유니크한 파일명으로 바꾼다.
        file.filename = file_name


        # S3 에 파일을 업로드한다.
        # aws 의 서비스들을 파이썬 코드로 작성할 수 있는
        # boto3 라이브러리를 이용해서 코드를 작성한다.
        # 설치는 $ pip install boto3
        
        client = boto3.client('s3',
                     aws_access_key_id = Config.AWS_ACCESS_KEY,
                     aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY)
        
        try:
            client.upload_fileobj(file,
                                  Config.S3_BUCKET,
                                  file_name,
                                  ExtraArgs = {'ACL':'public-read',
                                               'ContentType':file.content_type})
        except Exception as e:
            return {'result':'fail',
                    'error':str(e)}, 500

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

 

테스트해보자!

 

 

정상적으로 작동 ^_^