🐥
【Python】postされたファイルを処理するために一時ファイルとして保存する【FastAPI】
結論
import shutil
import tempfile
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/get_file")
def process_file(
upload_file: UploadFile = File(...),
):
# suffixは保存するファイルの拡張子を指定(今回は".stl"を指定)
with tempfile.NamedTemporaryFile(delete=True, dir=".", suffix=".stl") as temp_file:
shutil.copyfileobj(upload_file.file, temp_file)
# with内であればtemp_file.nameでファイル名指定が可能
print(temp_file.name)
# ↓内部処理↓
やりたいこと
- APIのPOSTリクエストで特定のファイルをサーバ側に送り、サーバ側で処理したい。しかし、処理後はサーバ側にファイルを残さずに処理結果だけをAPIのResponseで返したい。
具体例
- APIリクエストで3DモデルのSTLファイルを送信し、サーバ側でOpen3Dを使ってPointCloud形式への変換や、軽量化などの処理をする場合
tempfileモジュールについて
Pythonで一時ファイルやディレクトリを作成する際は tempfile
モジュールを使用する。
ファイル名を今後の処理で必要としない場合は tempfile.TemporaryFile を使用する。今回は内部処理でファイル名を指定して読み込む必要があったため、作成された一時ファイルの名前の取得が可能な tempfile.NamedTemporaryFile を使用する。
FastAPIにおけるファイルの受け取り
APIからファイルを受け取る際に使用するクラスは File
と UploadFile
の2種類ありますが、今回は取り回しが良い UploadFile
を使用する。
受け取ったUploadFile
を一時ファイルなどに保存する際は shutil.copyfileobj を使用する。
shutil.copyfileobj("コピー元のファイル名", "コピー先のファイル名")
ここでコピー先のファイル名を使用するため、名前指定ができる tempfile.NamedTemporaryFile
を使用する必要があった。
完成したソースコードの全体
記事先頭と同じソースコード
import shutil
import tempfile
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/get_file")
def process_file(
upload_file: UploadFile = File(...),
):
# suffixは保存するファイルの拡張子を指定(今回は".stl"を指定)
with tempfile.NamedTemporaryFile(delete=True, dir=".", suffix=".stl") as temp_file:
shutil.copyfileobj(upload_file.file, temp_file)
# with内であればtemp_file.nameでファイル名指定が可能
print(temp_file.name)
# ↓内部処理↓
参考文献
Discussion