자몽이 조아

[python,Flask]Flask의 @after_this_request 데코레이터 사용법 본문

개발공부

[python,Flask]Flask의 @after_this_request 데코레이터 사용법

Grapefruitgreentealoe 2025. 2. 10. 14:50
반응형

1. @after_this_request란?

Flask에서 @after_this_request 데코레이터는 특정 뷰 함수가 실행된 후, 응답을 반환하기 직전에 추가적인 처리를 할 수 있도록 해주는 기능입니다.

이는 요청이 끝난 후 임시 파일을 삭제하거나, 특정 로그를 남기는 등의 작업을 수행할 때 유용하게 사용할 수 있습니다.

2. 기본 사용법

@after_this_request는 뷰 함수 내에서 정의되어야 하며, 하나의 인자로 응답 객체 (response)를 받는 내부 함수를 필요로 합니다.

from flask import Flask, request, jsonify, send_file, after_this_request
import os
import tempfile

app = Flask(__name__)

@app.route('/generate-file', methods=['GET'])
def generate_file():
    with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
        file_path = tmp_file.name
        tmp_file.write(b"This is a temporary file.")
    
    # 요청이 완료된 후 파일 삭제
    @after_this_request
    def remove_file(response):
        try:
            os.remove(file_path)
        except Exception as e:
            print(f"Error deleting file {file_path}: {e}")
        return response
    
    return send_file(file_path, as_attachment=True, download_name="sample.txt", mimetype="text/plain")

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

3. @after_this_request가 필요한 이유

  • 임시 파일 자동 정리: 요청이 끝난 후 불필요한 파일을 정리하여 서버의 디스크 공간을 절약할 수 있습니다.
  • 응답 반환 후 후속 작업 수행: 예를 들어, API 호출 후 관련 로그를 저장하거나 추가적인 데이터를 업데이트할 수 있습니다.
  • Flask의 request lifecycle 활용: 일반적인 요청과 응답 과정 중 응답을 조작하거나 후처리를 간편하게 추가할 수 있습니다.

4. 다른 방법과의 비교

방법 장점 단점

@after_this_request 응답 후 자동 삭제, 요청별 개별 관리 가능 Flask 요청/응답이 끝난 후에만 작동
try-finally 코드 흐름이 직관적, 파일이 항상 삭제됨 응답이 진행 중이어도 삭제될 수 있음 (파일이 없음 오류 발생 가능)
백그라운드 스레드 사용 요청 종료 후에도 파일 정리 가능 관리가 어려울 수 있음, 오버헤드 발생 가능

4.1 try-finally 방식

@app.route('/generate-file-finally', methods=['GET'])
def generate_file_finally():
    file_path = "/tmp/sample.txt"
    with open(file_path, "w") as f:
        f.write("This is a temporary file.")
    
    try:
        return send_file(file_path, as_attachment=True, download_name="sample.txt", mimetype="text/plain")
    finally:
        os.remove(file_path)

장점: 파일이 항상 삭제됨
단점: 응답이 진행 중이어도 삭제될 수 있어 FileNotFoundError 발생 가능

4.2 백그라운드 스레드 방식

import threading

def delete_file_later(file_path):
    threading.Timer(5.0, os.remove, args=[file_path]).start()

@app.route('/generate-file-thread', methods=['GET'])
def generate_file_thread():
    file_path = "/tmp/sample.txt"
    with open(file_path, "w") as f:
        f.write("This is a temporary file.")
    
    delete_file_later(file_path)
    return send_file(file_path, as_attachment=True, download_name="sample.txt", mimetype="text/plain")

장점: 요청이 끝난 후에도 파일 삭제 가능
단점: 스레드 관리가 어렵고, 불필요한 삭제 지연이 발생할 수 있음

4.3 @after_this_request 방식 (가장 권장되는 방식)

@app.route('/generate-file-after', methods=['GET'])
def generate_file_after():
    file_path = "/tmp/sample.txt"
    with open(file_path, "w") as f:
        f.write("This is a temporary file.")
    
    @after_this_request
    def remove_file(response):
        os.remove(file_path)
        return response
    
    return send_file(file_path, as_attachment=True, download_name="sample.txt", mimetype="text/plain")

장점: 요청별 개별 파일 관리 가능, 응답 후 안전하게 삭제됨
단점: Flask 요청 종료 후에만 실행됨

반응형
Comments