Flask API로 파일을 업로드하는 방법

이 기사에서는 플라스크 API로 파일을 업로드하는 방법에 대해 Python으로 코드를 제시합니다. 개발을 시작하기 전에 python library을 확인하고 설치하십시오. $ python3 -m venv venv로 개발을 위한 가상 환경(env)을 설정하고 $ source venv/bin/activate로 활성 환경을 설정할 준비를 하십시오.

다음 단계에서는 $ pip install flask로 플라스크를 설치하고 프로젝트에 폴더를 생성합니다.

app.py
/ static
  => css
     / style.css
  => img
     / upload_icon.png
     / success_icon.png
/ templates
  => index.html
  => download.html


마지막으로 $ pip3 install -r requirements.txt를 설치하고 $ pip freeze > requirements.txt로 라이브러리를 고정하여 설정을 완료합니다.

설정을 마치면 보안 파일 이름의 JSON, 플라스크 템플릿 및 유틸리티를 가져옵니다. 아래 코드를 따라갈 수 있습니다.

import os
import json
from flask import Flask, request, render_template, flash, redirect, url_for, send_from_directory
from werkzeug.utils import secure_filename


두 번째 단계에서는 파일 형식 확장명을 확인할 수 있는 상수를 제공해야 합니다(예: ".txt"파일 확인).

ALLOWED_EXTENSIONS = {'txt'}


세 번째 단계에서는 아래 코드에서 구성 파일 형식에 대한 새 인스턴스를 만들어야 합니다.

application = Flask(__name__)
application.secret_key = os.urandom(24)
application.config['UPLOAD_FOLDER'] = 'data'
application.config['MAX_CONTENT_LENGTH'] = 4 * 1024 * 1024  # 4MB max-limit.


그리고 ALLOWED_EXTENSIONS로 허용된 파일을 확인하기 위한 확장 프로그램을 만들어야 합니다.

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.',1)[1].lower() in ALLOWED_EXTENSIONS  


네 번째 단계는 브라우저로 파일을 업로드하기 위한 API를 만들어야 합니다. localhost IPhttp://127.0.0.1:5000/로 파일을 업로드하라는 사용자 요청이 있는 경우 시스템은 파일 부분을 확인하고 문서의 텍스트를 읽습니다.

# home page
@application.route('/', methods=['POST', 'GET'])
def upload_file():
    if request.method == 'POST':
       if 'file' not in request.files:
          flash('No file part')
          return redirect(request.url)

       file = request.files['file']

       read_text = []
       for text in request.files.get('file'):
          read_text.append(str(text).replace("b'",""))
       print(read_text[0])

       # if the user does not select a file, the browser submits an empty file without a filename.
       if file.filename == '':
         flash('No selected file')
         return redirect(request.url)

       # if the user submits a file with the correct format
       if file and allowed_file(file.filename):
         filename = secure_filename(file.filename)
         file.save(os.path.join(application.config['UPLOAD_FOLDER'], filename))
         os.remove(os.path.join(application.config['UPLOAD_FOLDER'], filename))
         return redirect(url_for('download_file'))

    return render_template('index.html')


업로드 파일 API를 이미 생성한 후. 그래서 다운로드 파일 API를 생성하겠습니다.

# download page
@application.route('/download', methods=['POST', 'GET'])
def download_file():
    if request.method == 'POST':
        if request.form['Download Result File'] == 'Download File':
            return send_from_directory(application.config['UPLOAD_FOLDER'], 'result_file.txt')


HTML 쪽에서는 템플릿 폴더에 index.html과 download.html을 생성해야 합니다.

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <title>Download File</title>
</head>

<body>
    <div class="container">
        <section class="vh-100 gradient-custom">
            <div class="text-center justify-content-between py-4 px-4 px-xl-5 bg-dark">
                <div class="text-white mb-2 mb-md-0">
                    <p>Download File</p>
                </div>
            </div>
            <div class="container-fluid h-custom py-4">
                <div class="h-100">
                    <div class="row d-flex justify-content-center align-items-center h-100">
                        <div class="col-12 col-md-9 col-lg-7 col-xl-6">
                            <div class="card" style="border-radius: 15px;">
                                <div class="card-body p-5">
                                    <form method=post enctype=multipart/form-data>
                                        <div style="text-align:center;">
                                            <div class="form-outline mb-4">
                                                <input type=file name=file>
                                            </div>
                                            <div class="form-outline mb-4">
                                                <button type=submit class="btn btn-primary">Upload</button>
                                            </div>
                                        </div>
                                    </form>

                                    {% with messages = get_flashed_messages() %} {% if messages %}
                                    <ul class=flashes>
                                        {% for message in messages %}
                                        <li>{{ message }}</li>
                                        {% endfor %}
                                    </ul>
                                    {% endif %} {% endwith %}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
</body>

</html>


다운로드.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
    <title>Download File Success</title>
</head>

<body>
    <div class="container">
        <section class="vh-100 gradient-custom">
            <div class="container-fluid h-custom py-4">
                <div class="h-100">
                    <div class="row d-flex justify-content-center align-items-center h-100">
                        <div class="col-12 col-md-9 col-lg-7 col-xl-6">
                            <div class="card" style="border-radius: 15px;">
                                <div class="card-body p-5">
                                    <h2 class="text-uppercase text-center mb-5">Download result file</h2>
                                    <form method=post>
                                        <div style="text-align:center;">
                                            <div class="form-outline mb-4">
                                                <input type="submit" name="Download Result File" value="Download BPMN File">
                                            </div>
                                        </div>
                                    </form>
                                    <div style="text-align:center;">
                                        <a href="{{url_for('upload_file')}}">Back to Upload File</a>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
</body>

</html>


결과 app.py

import os
import json
from flask import Flask, request, render_template, flash, redirect, url_for, send_from_directory
from werkzeug.utils import secure_filename

ALLOWED_EXTENSIONS = {'txt'}

application = Flask(__name__)
application.secret_key = os.urandom(24)
application.config['UPLOAD_FOLDER'] = 'data'
application.config['MAX_CONTENT_LENGTH'] = 4 * 1024 * 1024  # 4MB max-limit.

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.',1)[1].lower() in ALLOWED_EXTENSIONS

# home page
@application.route('/', methods=['POST', 'GET'])
def upload_file():
    if request.method == 'POST':
       if 'file' not in request.files:
          flash('No file part')
          return redirect(request.url)

       file = request.files['file']

       read_text = []
       for text in request.files.get('file'):
          read_text.append(str(text).replace("b'",""))
       print(read_text[0])

       # if the user does not select a file, the browser submits an empty file without a filename.
       if file.filename == '':
         flash('No selected file')
         return redirect(request.url)

       # if the user submits a file with the correct format
       if file and allowed_file(file.filename):
         filename = secure_filename(file.filename)
         file.save(os.path.join(application.config['UPLOAD_FOLDER'], filename))
         os.remove(os.path.join(application.config['UPLOAD_FOLDER'], filename))
         return redirect(url_for('download_file'))

    return render_template('index.html')

# download page
@application.route('/download', methods=['POST', 'GET'])
def download_file():
    if request.method == 'POST':
        if request.form['Download Result File'] == 'Download File':
            return send_from_directory(application.config['UPLOAD_FOLDER'], 'result_file.txt')

좋은 웹페이지 즐겨찾기