본문 바로가기
Fast API/fastapi 팁

[FastAPI] 이미지 파일 업로드 하기

by 붕어사랑 티스토리 2021. 12. 13.
반응형

백엔드 서버에 이미지 파일을 저장해야 하는 일이 있다.

 

가령 게시판에 사진을 올린다던지.

 

 

헌데 이미지파일을 DB에 저장하면 DB 쿼리 성능을 저하시킨다.

이때문에 서버에 이미지를 저장할 때에는

 

  • 서버의 파일 시스템에 이미지를 저장
  • DB에는 이 파일의 URL만 저장해야한다

 

 

아래는 FastAPI에 파일을 저장하는 예제이다.

 

파일 파라미터에는 UploadFile을 사용한다

 

그리고 파일명이 중복되지 않도록 파일명을 저장되는 시간 + 임의의 램덤해시값으로 저장한다.

from fastapi import UploadFile, File

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_DIR = os.path.join(BASE_DIR,'static/')
IMG_DIR = os.path.join(STATIC_DIR,'images/')
SERVER_IMG_DIR = os.path.join('http://localhost:8000/','static/','images/')

@router.post('/upload-images')
async def upload_board(in_files: List[UploadFile] = File(...)):
    file_urls=[]
    for file in in_files:
        currentTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        saved_file_name = ''.join([currentTime,secrets.token_hex(16)])
        print(saved_file_name)
        file_location = os.path.join(IMG_DIR,saved_file_name)
        with open(file_location, "wb+") as file_object:
            file_object.write(file.file.read())
        file_urls.append(SERVER_IMG_DIR+saved_file_name)
    result={'fileUrls' : file_urls}
    return result

 

그리고 저장된 파일을 읽어오려면 아래와 같이 File Response를 이용하여 클라이언트에 전달해주면 된다.

 

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_DIR = os.path.join(BASE_DIR,'static/')
IMG_DIR = os.path.join(STATIC_DIR,'images/')
SERVER_IMG_DIR = os.path.join('http://localhost:8000/','static/','images/')


@router.get('/images/{file_name}')
def get_image(file_name:str):
    return FileResponse(''.join([IMG_DIR,file_name]))

 

반응형

 

 

docs에서 실행하면 아래와 같이 저장된 파일의 url을 전달 받는다

 

서버에 파일이 저장됨을 확인

 

 

 

 

반응형

댓글