개발학습일지

[Restful API] 사진 / 파일 업로드 하는 API _ boto3를 이용해서 S3에 업로드 하기 본문

Restful API

[Restful API] 사진 / 파일 업로드 하는 API _ boto3를 이용해서 S3에 업로드 하기

처카푸 2024. 5. 28. 16:36

사진 / 파일 업로드 하는 API 개발

- boto3를 이용해서 S3에 업로드 하기

 

API 설계하기 전,AWS S3 버킷 생성 하기https://msdev-st.tistory.com/155

 

[AWS] S3 버킷 만들기 _ 스토리지 만들어서 사용하기

S3 버킷 만들기 _ 스토리지 만들어서 사용하기AWS의 S3란? Simple Storage Service의 약자로 파일 서버의 역할을 하는 서비스다. 일반적인 파일서버는 트래픽이 증가함에 따라서 장비를 증설하는 작

msdev-st.tistory.com

 

Postman을 활용한 API 설계

- 사진 / 파일을 요청하려면 Body에 form-data를 사용해서 request 한다.

 

 

API 개발 중인 가상환경에,

파이썬 코드로 AWS의 여러 서비스들을 사용할 수 있도록,

AWS가 만들어준 라이브러리를 설치한다.

$ pip install boto3

 

깃허브랑 연동하고,

API 개발 환경 모두 설정한다 app.py 등...

 

사진 업로드하는 코드 작성

# 기본 플라스크 임포트
from flask_restful import Resource
from flask import request

# 파일 이름 유니크하게 저장하기 위한 데이트타임 임포트
from datetime import datetime

# AWS의 여러 서비스를 이용하기 위한 라이브러리
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
		
        # .get() 사용
        file = request.files.get('photo')
        print(file)

        # 파일의 타입을 검사한다 (이미지 파일만 가능하다)
        if 'image' not in file.content_type :
            return {"result":"fail", "error":"이미지파일만 업로드 가능합니다."}, 400
		
        # [] 사용
        content = request.form['content']
        print(content)

        # 파일을 s3에 업로드 해야 하는데,
        # 먼저, 파일명은 유니크 해야 한다.
        # 따라서, 유니크한 파일명으로 바꿔서 업로드 한다.

        # 현재시간과 유저아이디 등을 조합해서 만든다. 여기서는 현재 시간만!
        current_time = datetime.now()

        # file.content_type.split('/')[-1]  'image/jpeg'이런 파일이름의 뒤 확장자만 가져온다.
        file_name = current_time.isoformat().replace(':','_') + '.' + file.content_type.split('/')[-1]
        print(file_name)

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

        ### s3에 파일을 업로드 ###
        # aws의 서비스들을 파이썬코드로 작성 할 수 있는 
        # boto3 라이브러리를 이용해서 코드를 작성한다.
        # ( 설치는, $ pip install boto3 )
		# Config = 내가 만든 보안이 필요한 데이터를 저장하는 클래스
        client = boto3.client('s3' ,
                               aws_access_key_id = Config.AWS_ACCESS_KEY,
                               aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY)

        # ExtraArgs = {'ACL':'public-read','ContentType':'image/jpg'} -> content type을 이미지/jpg로 받겠다!
        # ExtraArgs = {'ACL':'public-read','ContentType':file.content_type}) -> 파일의 타입대로 받겠다!!
        # 클라이언트를 일시킨다!
        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}

 

 

 


* 설치 라이브러리 설명 사이트 : boto3

https://pypi.org/project/boto3/

 

boto3

The AWS SDK for Python

pypi.org

 

* 파일 타입  ->  file.content_type

: 예 ) 'image/jpeg', 'image/png'

사이트에서 원하는 타입을 찾아 파일 타입 작성하면 된다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

 

Common MIME types - HTTP | MDN

This topic lists the most common MIME types with corresponding document types, ordered by their common extensions.

developer.mozilla.org