티스토리 뷰
반응형
2024. 01. 01 업데이트
# 서론
FastAPI 프레임워크에서 이미지 (multipart form data)를 업로드 하는 방법을 공유한다.
* FastAPI 공식문서 Request Files 탭에 기록되어 있음
https://fastapi.tiangolo.com/tutorial/request-files/
해당 글에서는 파일을 서버 로컬에 저장하는 방식으로 구현한다.
파일을 스트림으로 읽어서, 외부 스토리지 (AWS S3같은 곳)에 저장하는 방법은 다음글을 참조하면 좋을 것 같다.
# 업로드
FastAPI 에서 파일 업로드를 담는 객체는 UploadFile이 있다.
타입 힌팅을 통해서 라우터단에 파라미터로 받는다.
@app.post("/photo")
async def upload_photo(file: UploadFile):
UPLOAD_DIR = "./photo" # 이미지를 저장할 서버 경로
content = await file.read()
filename = f"{str(uuid.uuid4())}.jpg" # uuid로 유니크한 파일명으로 변경
with open(os.path.join(UPLOAD_DIR, filename), "wb") as fp:
fp.write(content) # 서버 로컬 스토리지에 이미지 저장 (쓰기)
return {"filename": filename}
해당 코드와 같이 file을 읽고, 원하는 디렉토리에 쓰면 파일을 업로드 하는 기능을 구현 할 수 있다.
파일 이름을 유니크화 하여 서버단에 저장하는 로직이다.
주의! file 이라는 이름으로 해당 파일 객체를 받으므로, 클라이언트단에서는 file이라는 키값으로 이미지나 파일을 보내야 받을 수 있다! 안 그러면 422 Unprocessable Entity 에러를 발생시킨다.
# 다운로드
다운로드는 FastAPI에서 제공하는 FileResponse를 통해서 아주 손 쉽게 할 수 있다.
# 사진 다운로드
@app.get("/download/photo/{photo_id}")
async def download_photo(photo_id: int, db: Session = Depends(get_db)):
find_photo: Photo = db.query(Photo).filter_by(photo_id=photo_id).first()
return FileResponse(find_photo.src)
이런식으로 해당 파일의 경로를 넣어서 리턴해주면 이미지가 내려간다.
여기서는 디비 질의 부분도 포함되어있는데, 이는 파일 정보를 디비에 넣은 경우라 그렇다.
반응형