AWS S3 - 파이썬으로 이미지 파일 업로드하기

반응형

목표

  • S3에 이미지 파일을 업로드
  • RDS DB에 이미지의 URL과 내용 저장

boto3

파이썬용 AWS 소프트웨어 개발 킷

Amazon S3, EC2, DynamoDB 등 AWS 서비스와 쉽게 통합


boto3 라이브러리 설치

  • S3에 파일을 업로드하기 위해선 AWS 라이브러리가 필요
  • boto3 : AWS의 서비스를 프로그래밍 코드로 이용 할 수 있게 해주는 라이브러리
pip install boto3

Visual Studio Code

메인 파일 : app.py

  • 기능 : API 구축, 환경변수 설정, 리소스 경로 생성
from flask import Flask
from flask_jwt_extended import JWTManager
from flask_restful import Api

from ref.config import Config

from resources.posting import PostingResource

# API 서버를 구축하기 위한 기본 구조
app = Flask(__name__)

# 환경변수 셋팅
app.config.from_object(Config) # 만들었던 Config.py의 Config 클래스 호출

# restfulAPI 생성
api = Api(app)

# 경로와 리소스(api코드) 연결
api.add_resource(PostingResource, '/posting')

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

추가 리소스 파일 : posting.py

  • 기능
    • 파이썬 코드로 AWS 서비스 사용
    • 이미지 파일을 업로드하여 클라우드 서버(S3)에 저장
    • 이미지 url과 내용을 데이터베이스(RDS)에 저장
  • 기능 설계
    • 유저에게 파일을 받아 s3에 파일 업로드 (boto3 라이브러리 사용)
      • 파일이름은 현재 시간으로 생성 (파일 이름의 중복 방지)
    • 업로드한 파일 주소와 입력 받은 내용 DB에 저장
  • 참고
    • 비공개 사항 : connection, Config
      • connection : AWS RDS DB 연동 정보 내포
      • Config : S3의 액세스키와 시크릿키 내포
from flask import request
from flask_restful import Resource
import mysql.connector
from ref.mysql_connection import get_connection
from ref.config import Config
from datetime import datetime
import boto3

class PostingResource(Resource) :
	# 이미지와 내용 포스팅
    def post(self) :
        # 클라이언트로부터 데이터 받기
        # photo(file), content(text)
        if 'photo' not in request.files :
            return {"error" : "파일을 업로드해주세요."}, 400

        file = request.files['photo']
        content = request.form['content']

        # 파일명 변경, 파일명은 유니크 (중복이 없도록)
        current_time = datetime.now()
        new_file_name = current_time.isoformat().replace(':', '_') + '.png'

        # 클라이언트에서 받은 파일의 이름 변경
        file.filename = new_file_name

        # S3에 업로드
        # AWS 라이브러리 사용 (boto3)
        s3 = boto3.client('s3', aws_access_key_id = Config.ACCESS_KEY, \
                    aws_secret_access_key = Config.SECRET_ACCESS)
        try :
            s3.upload_fileobj(file, Config.S3_BUCKET, file.filename, \
                ExtraArgs={'ACL':'public-read', 'ContentType':file.content_type})
        except Exception as e :
            return {'error' : str(e)}, 500
        
        # RDS DB에 이미지 주소, 내용 저장
        try :
            connection = get_connection()
            query = '''
                    insert into posting
                        (content, imgUrl)
                    values
                        (%s ,%s);
                    '''
            record = (content, new_file_name)
            cursor = connection.cursor()
            cursor.execute(query, record)
            connection.commit()
            cursor.close()
            connection.close()
        except Exception as e :
            return {'error' : str(e)}, 500

        return {'result' : 'success',
                'image_url' : Config.S3_LOCATION + file.filename}

POSTMAN - 이미지 파일을 업로드하고 이미지에 대한 내용 저장

  • API 기능 : 사진과 내용 저장
  • POST - Body - form-data
    • KEY : VALUE 입력
      • photo : key 우측에 test -> file 변경하여 이미지 파일 선택
      • content : VALUE에 내용 작성


AWS S3 - 파일 업로드 확인


MySQL - 이미지 주소와 내용 확인

 

반응형