이전 내용
[파이썬] 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
'[파이썬 Projects] > <파이썬 웹개발>' 카테고리의 다른 글
[파이썬] FastAPI - ORM 연동하기(SQLAlchemy) (0) | 2025.04.28 |
---|---|
[파이썬] FastAPI - 웹소켓 (0) | 2025.04.27 |
[파이썬] FastAPI - 쿼리 매개변수, 경로 매개변수, 백그라운드 태스크 (0) | 2025.04.27 |
[파이썬] FastAPI - 정적 파일, API Router (0) | 2025.04.27 |
[FastAPI] FastAPI + Streamlit + PostgresSQL (3) (0) | 2025.04.26 |