본문 바로가기

[FastAPI] Response vs FileResponse 차이와 사용법

@Jeeqong 2025. 4. 2. 04:59
반응형

 

1. 개요

FastAPI에서 파일 다운로드 기능을 구현할 때 자주 사용하는 두 가지 방식이 있다: ResponseFileResponse.
처음 FastAPI를 접하는 사람이라면 둘의 차이와 어떤 상황에 어떤 것을 써야 할지 헷갈릴 수 있다.
이 글에서는 이 두 방식의 차이를 실제 예제와 함께 비교해본다.

2. Response vs FileResponse 비교

2.1 기본 개념

  • Response: FastAPI의 가장 기본적인 응답 객체로, JSON, 텍스트, 바이너리 등 다양한 타입을 다룰 수 있다.
  • FileResponse: FastAPI에서 파일 다운로드용으로 특별히 최적화된 응답 객체다. 파일 경로만 넘기면 내부적으로 스트리밍 처리된다.

2.2 차이점 정리

항목 Response FileResponse
사용 방식 파일 열고 .read() 후 응답 경로만 넘기면 자동 스트리밍
메모리 효율 전체 파일을 메모리에 올림 스트리밍 방식으로 메모리 부담 적음
다운로드 헤더 설정 직접 수동 설정 자동으로 Content-Disposition 적용
권장 상황 소용량 파일, 테스트용 대용량 파일 다운로드 (CSV, PDF 등)

3.  예제 코드

3.1 Response 방식

from fastapi import FastAPI, Response
import os

app = FastAPI()

@app.get("/download-response")
def download_via_response():
    file_path = "data/sample.csv"
    if not os.path.exists(file_path):
        return {"message": "파일 없음"}

    with open(file_path, "rb") as file:
        content = file.read()

    return Response(
        content,
        media_type="text/csv",
        headers={"Content-Disposition": "attachment; filename=sample.csv"}
    )

3.2 FileResponse 방식

from fastapi import FastAPI
from fastapi.responses import FileResponse
import os

app = FastAPI()

@app.get("/download-file")
def download_via_fileresponse():
    file_path = "data/sample.csv"
    if not os.path.exists(file_path):
        return {"message": "파일 없음"}

    return FileResponse(
        file_path,
        media_type="text/csv",
        filename="sample.csv"
    )

4. 언제 어떤 걸 써야 할까?

4.1 Response 추천 상황

  • 단순한 JSON이나 텍스트 데이터 응답
  • 임시로 바이너리 내용을 생성해서 바로 응답할 때

4.2 FileResponse 추천 상황

  • 실제 파일 시스템에 저장된 파일을 다운로드해야 할 때
  • CSV, PDF, 이미지 등 대용량 정적 파일
  • 브라우저에서 다운로드 동작이 필요한 경우

5. 결론

FastAPI에서 간단한 응답이라면 Response를 써도 무방하지만,
실제 운영 환경에서 파일 다운로드가 필요한 경우에는 FileResponse가 훨씬 안전하고 효율적이다.
특히 CSV나 PDF처럼 정적 파일을 다룰 땐 무조건 FileResponse를 사용하는 것을 추천한다.

반응형
Jeeqong
@Jeeqong :: JQVAULT

Jeeqong's vault : 정보/기록을 쌓아두는 공간 웹개발 포스팅 일상 리뷰를 기록하는 공간입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차