Fast API/fastapi 팁

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

붕어사랑 티스토리 2021. 12. 13. 11:59
반응형

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

 

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

 

 

헌데 이미지파일을 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을 전달 받는다

 

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

 

 

 

 

반응형