Liquidsのロゴ Liquids

ファイルアップロード【FastAPI】

FastAPI
Python

このwikiではFastAPIでファイルのアップロード機能を作成する方法について紹介していきます。

FastAPIでファイルを扱うにはリクエストボディがmultipart/formdataになります。このmultipart/formdataをFastAPIで扱えるようにするには、あらかじめpython-multipartのインストールが必要です。

pip install python-multipart

FastAPIでファイルのアップロード機能を作る方法として、以下の2通りの実装方法があります。

  • Annotated[bytes, File()]でアノテーションする
  • UploadFileでアノテーションする

それぞれ紹介していきます。

Annoted[bytes, File()] を用いたファイルのアップロード方法では、下記コードのようにAnnoted[bytes, File()]でアノテーションを行います。

from fastapi import FastAPI, File
from typing import Annotated

app = FastAPI()

@app.post('/')
def file_upload(file: Annotated[bytes, File()]):
    return file.decode()

Swagger UIで確認してみると、ファイルをアップロードできるようになっています。

また、リクエストボディもapplication/jsonではなく、multipart/form-dataとなっています。

実際に下記のテキストファイルを与えてみます。

THIS IS TEST TEXT...

レスポンスにテキストファイルの内容が返ってきており、ちゃんとファイルをアップロードできていることがわかりました。

Annoted[bytes, File()]で受け取ることができていたのは、ファイルのデータでした。

一方で、UploadFileでは受け取れるものがやや異なります。

<引数>.fileで、一時的なファイルオブジェクトにアクセスできるため、データはPythonのファイルオブジェクトとして読み取ることができます。

また、データにアクセスするだけでなく、filenameでファイルの名前、content_typeContent-typeを取得することもできます。

from fastapi import FastAPI, UploadFile

app = FastAPI()

@app.post('/')
def file_upload(file: UploadFile):
    print(file.filename)
    # test_upload.txt
    content_byte = file.file.read()
    print(file.content_type)
    # text/plain
    print(type(content_byte))
    return content_byte.decode()


実際に下記のテキストファイルを与えてみます。

THIS IS TEST TEXT...

2つのファイルのアップロード方法について紹介しましたが、これらはどのようにして使い分けるのでしょうか?

Annoted[bytes, File()]では、受け取ったデータはメモリーに保存されます。小さなサイズのファイルであれば良いですが、大きなファイルを受け取る場合、メモリーに保存するのは良くないかもしれません。

一方で、UploadFileを使用した方法では、一時ファイルとしてアクセスができるように、補助記憶に保存されています(ドキュメントによると一定程度まではメモリーに保存されるらしい)。そのため、動画などの大きなファイルをアップロードする際にはメモリーを圧迫しないようにUploadFileを使用した方が良いと言えます。

Liquidsのロゴ Liquids

Liquidsは誰でも投稿・編集ができる技術Wikiコミュニティ📝です。

あなたもLiquidsで技術Wikiを
書いてみませんか?