프레임워크/FastAPI

[FastAPI] FastAPI [18] Request Files

:) :) 2023. 5. 9. 16:25

https://fastapi.tiangolo.com/tutorial/request-files/

 

Request Files - FastAPI

Request Files You can define files to be uploaded by the client using File. Info To receive uploaded files, first install python-multipart. E.g. pip install python-multipart. This is because uploaded files are sent as "form data". Import File Import File a

fastapi.tiangolo.com

<FastAPI 공식문서 참조>

 

0. Request Files

File 라이브러리를 사용하여 클라이언트가 파일을 업로드 할 수 있도록 구현할 수 있다.

 

1. Import File

File과 UploadFile library를 import하자.

from typing import Annotated

from fastapi import FastAPI, File, UploadFile

 

 

2. Define File Parameters

File Parameter는 다음과 같이 선언한다(Body 혹은 Form과 비슷하게).

app = FastAPI()


@app.post("/files/")
async def create_file(file: Annotated[bytes, File()]):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

* File body로 선언하려 해도 File을 사용해야 한다. 그렇지 않으면 paramter가 Query 혹은 Body(JSON) parameter로 해석될 수 있기 때문이다.

 

* path operation function의 parameter를 bytes로 선언시,

FastAPI는 파일을 읽고 bytes 형태의 내용을 전달한다.

이는 전체 내용이 메모리에 저장됨을 의미해 작은 크기의 파일에만 사용하도록 하자.

 

 

3. File Parameters with UploadFile

 여러 상황에서 UploadFile 형식이 더 유용할 때가 있다.

아래는 UploadFile 형의 parmeter를 선언하는 예시다.

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

 이는 위의 bytes형을 return하는 file형식과 비교해 다음과 같은 장점을 가진다.

  • spooled file을 사용한다.
    • 제한된 크기의 메모리에만 저장되며, 이를 초과하는 경우 디스크에 저장된다.
      • 따라서 대용량 파일들은 메모리 자원을 엄청나게 갉아먹지 않고, 따라서 이들 처리에 적합하다.
  • 업로드한 파일의 metadata를 얻을 수 있다.
  • file-like interface를 가지고 있다(async).
  • python SpooledTemporaryFile 객체를 반환하는데, 이는 file-like object를 필요로하는 다른 라이브러리에 직접 전달할 수 있다.

 

 

3-1. Attributes of UploadFile

UploadFile 자체의 속성을 살펴보자.

  • filename : 업로드 된 파일의 파일명이다. 문자열 형식이다. (예: myimage.jpg)
  • content_type : 파일 형식이다. 문자열로 되어 있다. (예: image/jpeg)
  • file : SpooledTemporaryFile 객체이다. 이는 python에서 사용되는 file 형식이다.

 

3-2. async method of UploadFile

  • write(data) : data를 파일에 작성한다.
  • read(size) : 파일의 바이트 및 글자의 size (int)를 읽는다.
  • seek(offset) : 파일 내 offset (int) 위치의 바이트로 이동한다.
    • await foo.seek(0) 를 사용하면 파일의 시작부분으로 이동한다.
    • await foo.read() 사용 후 내용을 다시 읽을 때 유용하다.
  • close() : 파일을 닫는다.

위 모두 async 메소드라 await 키워드와 함께 사용해야 한다.

 

 

예를 들어, async path operation function의 내부에서 다음과 같이 내용을 가져올 수 있다.

contents = await myfile.read()

 

일반적인 함수라면 아래와 같이 파일에 직접 접근할 수 있다.

contents = myfile.file.read()

 

 

4. UploadFile with Additional Metadata

다음은 메타데이터와 함께 File 자료형을 사용하는 예시이다.

@app.post("/files/")
async def create_file(file: Annotated[bytes, File(description="A file read as bytes")]):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(
    file: Annotated[UploadFile, File(description="A file read as UploadFile")],
):
    return {"filename": file.filename}

 

 

5. Multiple File Uploads

 동시에 여러 파일을 업로드하는 것이 가능하다.

여러 파일은 Form data 형태로 전송된 동일한 Form field에 연동된다.

이러한 기능을 사용하기 위해 bytes의 List 혹은 UploadFile을 선언해야 한다.

@app.post("/files/")
async def create_files(files: List[bytes] = File()):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile]):
    return {"filenames": [file.filename for file in files]}

 

get 연산은 다음과 같다.

@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
    """
    return HTMLResponse(content=content)

 

 

6. Recap

Form type의 매개변수로써 업로드할 파일을 선언할 경우 File을 사용하자.

 

 

 

7. Reference

https://fastapi.tiangolo.com/tutorial/request-files/

 

Request Files - FastAPI

Request Files You can define files to be uploaded by the client using File. Info To receive uploaded files, first install python-multipart. E.g. pip install python-multipart. This is because uploaded files are sent as "form data". Import File Import File a

fastapi.tiangolo.com