TOP
본문 바로가기
[파이썬 Projects]/<파이썬 웹개발>

[파이썬] FastAPI - 스트리밍 응답

by 기록자_Recordian 2025. 4. 27.
728x90
반응형
이전 내용
 

[파이썬] FastAPI - 쿼리 매개변수, 경로 매개변수, 백그라운드 태스크

이전 내용 [파이썬] FastAPI - 정적 파일, API Router이전 내용 [파이썬] FastAPI - FastAPI와 Jinja2 고급 문법시작에 앞서해당 내용은 , Dave Lee 지음. BJ Public 출판.내용을 토대로 작성되었습니다. 보다 자세한

puppy-foot-it.tistory.com


스트리밍 응답

 

◆ 스트리밍 응답(streaming response)

Streaming Response는 클라이언트에게 데이터를 점진적으로 전송하는 방식으로, 한 번에 모든 데이터를 전송하는 것이 아니라 필요에 따라 데이터를 조금씩 전송하는 방식을 의미한다. 

[Streaming Response의 특징]

  • 메모리 효율성: 대량의 데이터를 전송할 때 메모리 사용량을 줄일 수 있다. 전체 데이터를 메모리에 올려 두지 않고, 필요할 때마다 조금씩 읽어서 전송한다.
  • 실시간 데이터 전송: 클라이언트는 요청한 데이터를 즉시 받기 시작할 수 있으며, 서버는 데이터를 생성하는 대로 전송한다. 이는 비디오 스트리밍이나 이벤트 로그 전송과 같은 사용 사례에서 유용하다.
  • 감소된 대기 시간: 데이터를 준비하는 데 필요한 시간을 단축시켜 기본적인 응답 대기 시간을 줄일 수 있다.

FastAPI에서는 StreamingResponse 클래스를 사용하여 이러한 기능을 구현할 수 있다.

예를 들어 서버에서 큰 CSV 파일을 생성하고 이를 사용자에게 제공해야 한다고 가정할 경우, 이때 스트리밍 응답을 사용하면 파일을 조각조각 나눠서 전송할 수 있으므로 메모리와 네트워크 자원을 효율적으로 사용할 수 있다.

from fastapi import FastAPI 
from fastapi.responses import StreamingResponse  # StreamingResponse 
import csv
import io

app = FastAPI()

def csv_streamer():  # CSV 데이터를 점진적으로 생성하는 함수.
    data = [["name", "age"], ["alice", 32], ["bob", 29]]  
    output = io.StringIO()  # 메모리 내에서 문자열을 다루기 위한 StringIO 객체 생성
    writer = csv.writer(output)  # CSV 작성기를 사용하여 StringIO 객체에 CSV 형식으로 데이터 작성
    
    for row in data:  # 데이터를 루프를 통해 반복
        writer.writerow(row)  # 현재 행을 CSV 형식으로 작성
        yield output.getvalue()  # 작성된 내용을 클라이언트에 반환
        output.flush()  # 버퍼를 플러시하여 내용을 즉시 쓰도록 함
        output.truncate(0)  # 문자열 버퍼의 내용을 지워서 다음 데이터를 추가할 준비를 함
        output.seek(0)  # 버퍼의 위치를 처음으로 리셋

@app.get("/csv")  # /csv 경로에 대한 GET 요청을 처리하는 엔드포인트 생성
def get_csv():  # 클라이언트의 요청이 들어오면 호출되는 함수
    return StreamingResponse(  # StreamingResponse를 사용하여 스트리밍 응답을 반환
        csv_streamer(),  # 위에서 정의한 csv_streamer() 함수를 호출하여 데이터를 스트리밍
        headers={"Content-Type": "text/csv"}  # 응답 헤더에 CSV 형식임을 표시
    )
  • csv_streamer: 이 함수는 CSV 데이터를 생성하는 생성기(generator)이다.
    - 데이터 정의: data 변수에 이름과 나이를 가진 리스트를 정의.
    - io.StringIO: 메모리 내에서 문자열을 다루기 위한 객체. CSV 내용을 이 객체에 작성.
    - CSV 작성기: csv.writer 클래스를 사용하여 CSV 형식으로 데이터를 작성.
    - 데이터 작성 및 스트리밍: 루프를 통해 각 행을 CSV로 작성하고, yield를 통해 현재까지 작성된 내용을 반환. flush, truncate, 및 seek 메서드를 사용하여 다음 데이터를 추가하기 전에 버퍼를 정리.
  • StreamingResponse 객체: csv_streamer() 함수에서 생성된 스트림을 응답으로 전달한다. header={"Content-Type" : "text/csv"}를 설정함으로써 응답의 MIME 타입이 CSV 임을 명시한다. 이 헤더는 웹 브라우저나 다른 클라이언트가 응답을 받았을 때, 데이터가 CSV 형식임을 인식하고 적절하게 처리할 수 있도록 돕는다.
  • @app.get("/csv") 데코레이터: /csv 경로로 들어오는 HTTP GET 요청을 get_csv() 함수로 라우팅한다. 해당 함수는 StreamingResponse를 반환함으로써 요청을 받는 즉시 클라이언트에게 데이터 스트리밍을 시작한다.

▶ 클라이언트는 파일 전체를 다운로드하지 않고도 스트림의 일부를 실시간으로 받아볼 수 있다.

※ yield: 파이썬의 제너레이터(generator)에서 사용하는 키워드. 함수를 제너레이터로 만들어 주며, 제너레이터는 이터레이터(iterator)를 생성
▶ 함수를 호출할 때 모든 값을 한 번에 반환하는 대신, yield를 사용하면 함수가 중지되고, 현재 상태를 기억한다. 이후 다시 호출되면 그 다음부터 실행된다.


※ flush: 버퍼에 저장된 데이터를 강제로 즉시 기록하여 다른 곳(예: 파일, 네트워크)으로 전송. 일반적으로 I/O 작업에서 데이터가 빠르게 처리되는 것을 보장
▶ 버퍼 내용이 필요할 때마다 호출하여 데이터를 즉시 전달하도록 한다. 파일에 데이터를 쓸 때, 시스템이 자동으로 버퍼를 비우지 않으면, 데이터를 잃을 수 있다.

※ truncate: 파일 또는 문자열 버퍼의 크기를 줄이거나 특정 위치에서 자르는 기능 제공
▶ truncate(size)를 호출하면 해당 위치에서 버퍼의 크기를 줄이고, 그 위치 이후의 데이터는 삭제된다. 인수를 주지 않으면 현재 위치에서 모든 데이터를 삭제한다.

seek: 파일 또는 문자열 버퍼의 현재 위치를 변경할 수 있는 방법 제공. 즉, 읽기 또는 쓰기 작업을 시작할 위치를 설정

▶ seek(offset, whence)를 사용하여 파일의 특정 위치로 이동한다. offset은 이동할 바이트 수이고, whence는 기준 위치를 지정한다.
0: 파일의 시작 1: 현재 위치 2: 파일의 끝

 

http://127.0.0.1:8000/csv 경로로 접속하게 되면 csv 파일이 다운로드 된다.


StreamingResponse

 

StreamingResponse는 FastAPI에서 스트리밍 응답을 생성하기 위해 사용되는 클래스다. 이 클래스는 큰 데이터를 청크 단위로 나누어 클라이언트에게 순차적으로 전송할 때 유용하며, 특히 파일 다운로드, 실시간 데이터 전송, 대용량 데이터 처리 드으이 경우에 사용된다.

 

[주요 매개변수]

  • content: 클라이언트에 전송할 데이터. 데이터를 생성하는 제너레이터 함수나 이터러블 객체를 첫 번째 인자로 받는다. 이 데이터는 HTTP 응답으로 스트리밍된다. 제너레이터, iterable, 또는 비동기 iterable을 사용할 수 있다.
    예시: csv_streamer()와 같은 제너레이터 함수.
  • media_type: HTTP 응답의 콘텐츠 유형. 일반적으로 클라이언트가 전송된 데이터의 형식을 알 수 있도록 설정한다.
    다양한 MIME 타입이 사용될 수 있다.
    예: text/plain, text/csv, application/json, application/octet-stream, image/jpeg, audio/mpeg 등.
  • status_code:HTTP 응답의 상태 코드를 설정한다. 기본값은 200.
    예시: 404, 500 등의 상태 코드 사용.
  • headers: 응답에 추가할 HTTP 헤더. 사전 형태로 전달된다.
    예시: {"Content-Disposition": "attachment; filename=myfile.txt"}와 같은 형식으로 헤더를 추가할 수 있습니다.
  • background: 요청이 완료된 후 백그라운드에서 실행할 작업을 지정할 수 있다. 비동기 처리나 크고 복잡한 작업을 수행할 때 유용하다.

[media_type 목록]

  • text/plain: 일반적인 텍스트 데이터.
  • text/html: HTML 형식의 콘텐츠.
  • text/csv: CSV (Comma-Separated Values) 형식의 데이터.
  • text/xml: XML 형식의 텍스트 데이터.
  • application/json: JSON 형식의 데이터.
  • application/xml: XML 형식의 데이터.
  • application/octet-stream: 이진 데이터의 일반적인 형식.
  • application/pdf: PDF (Portable Document Format) 파일.
  • application/zip: ZIP 압축 파일.
  • application/vnd.ms-excel: Microsoft Excel 파일.
  • application/x-www-form-urlencoded: HTML 폼을 통해 제출된 데이터
  • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: Microsoft Excel 2007 이상의 파일
  • image/jpeg: JPEG 형식의 이미지.
  • image/png: PNG 형식의 이미지.
  • image/gif: GIF 형식의 이미지
  • audio/mpeg: MPEG 형식의 오디오 파일.
  • audio/wav: WAV 형식의 오디오 파일.
  • audio/ogg: Ogg Vorbis 오디오 파일.
  • video/mp4: MP4 형식의 비디오 파일.
  • video/x-msvideo: AVI 형식의 비디오 파일.
  • application/x-www-form-urlencoded: HTML 폼 데이터를 전송할 때 사용.
  • image/svg+xml: SVG 형식의 벡터 이미지.
from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()

# 데이터를 스트리밍하는 제너레이터 함수
def data_generator():
	for i in range(100):
    	yield f"data chunk {i}/n"

@app.get("/download-json")
def download_json():
    data = {"message": "Hello, World!"}
    return StreamingResponse(
        iter([json.dumps(data)]),  # JSON 데이터 생성
        media_type="application/json"  # JSON 형식으로 응답
    )

@app.get("/download-image")
def download_image():
    file_path = "path/to/image.jpg"
    return FileResponse(
        file_path,
        media_type="image/jpeg"  # JPEG 이미지 전송
    )
    
@app.get("/stream")
def stream_data():
	generator = data_generator() # 데이터 생성을 위한 제너레이터 호출
    return StreamingResponse(
    	generator,
        media_type="text/plain"
    )

 


[참고]

가장 빠른 풀스택을 위한 플라스크 & FastAPI


다음 내용

 

[파이썬] FastAPI - 웹소켓

이전 내용 [파이썬] FastAPI - 스트리밍 응답이전 내용 [파이썬] FastAPI - 쿼리 매개변수, 경로 매개변수, 백그라운드 태스크이전 내용 [파이썬] FastAPI - 정적 파일, API Router이전 내용 [파이썬] FastAPI - F

puppy-foot-it.tistory.com

728x90
반응형