AWS/AWS 일반

[AWS] AWS S3 File Upload 방법 (by. Flask)

yubi5050 2022. 6. 12. 15:23

Flask의 Fileupload 기능을 통해 AWS S3로 Uplod 하는 방법

* 사전에 S3 Bucket 생성이 완료됬다고 가정.

 

👉 Library Install

pip install boto3
pip install Flask

 

👉 소스코드 : templates/index.html

  • Form Data 형식으로 Ajax 비동기 통신 POST로  endpoint로 upload한 File을 보낸다.
<!Doctype html>
<html lang="ko">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- JS -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    </style>
    <script>
        function save() {
            var form_data = new FormData($('#upload-file')[0]);
            
            $.ajax({
                type: 'POST',
                url: '/fileupload',
                data: form_data,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert("파일이 업로드 되었습니다!!");
                },
            });
        }
    </script>

</head>

<body>
<div class="wrap">
    <h2> 파일 업로드 </h3>
    <form id = "upload-file">
        <label for="post-url">이미지 파일</label>
        <input type="file" name="file"/>
    </form>
    <button type="button" onclick="save()">저장</button>
</div>
</body>
</html>

 

👉 소스코드 :  app.py

  • boto3는 aws 서비스와 연결해주는 라이브러리이다.
  • ACL : Access Control List로 정책이라고 보면 됨
  • Bucket 명과 Body를 채우고 put_object () 함수 호출
import boto3
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

@app.route('/')
def main():
    return render_template('index.html')

@app.route('/fileupload', methods=['POST'])
def file_upload():
    file = request.files['file']
    print(file)
    s3 = boto3.client('s3')
    # s3 = 	boto3.client('s3', aws_access_key_id = AWS_ACCESS_KEY, aws_secret_access_key = AWS_SECRET_KEY)
    s3.put_object(
        ACL="public-read",
        Bucket= "smkimtestbucket", # "{버킷이름}",
        Body=file, # 업로드할 파일 객체
        Key=file.filename, # S3에 업로드할 파일의 경로
        ContentType=file.content_type # 메타데이터 설정
    ) 
    return jsonify({'result': 'success'})

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

 

 

👉 추가 작성

Request 로 받은 File 객체가 아닌, PIL Image 등을 업로드 하는 경우 아래와 같이 작성해주면 된다.

import io
in_mem_file = io.BytesIO()
pil_image.save(in_mem_file, 'PNG') 
in_mem_file.seek(0)

import boto3
s3 = boto3.client('s3')

s3.put_object(
    ACL="public-read",
    Bucket= "<버킷이름>",
    Body= "<업로드할 파일 객체>",
    Key="<S3에 업로드할 파일의 경로>",
    ContentType='image/png' # 메타데이터 설정
)