WebRTCで撮影した動画をFastAPIにPOSTでファイルアップロードするときハマったこと

TL;DR 解決

下記でファイルアップロードできます。

Javascript側(送る側)

var f = new FormData();
var filename = "something.webm"
f.append("video", buffer, filename); // <=ここではまった
let xhr = new XMLHttpRequest();
xhr.open('POST', window.location.origin + '/uploadVideo', true);
xhr.send(f);

ちなみにbufferはblobです。

FastAPI側(受け取る側)

@app.post("/uploadVideo")
async def uploadVideo(video: UploadFile = File(...)): # <=ここではまった
    video_data = await video.read()
    upload_path = pathlib.Path(f'static/received_videos/{video.filename}')
    with upload_path.open(mode="wb") as f:
        f.write(video_data)
    return {"filename": video.filename}

ハマったところ2点

  • 必要なライブラリ
  • FastAPIの引数名

必要なライブラリ

下記が必要そう

pip install python-multipart

参考:Uploading images in FastAPI post request causes 400 Bad Request - Stackoverflow

FastAPIの引数名

async def uploadVideo(video: UploadFile = File(...)):

ここでvideoとなっているところは多くの記事でfileとかになっています。

FastAPIのPOSTで受け取る際はその引数の名前を送る側と同じにすることで受け取れるようになっているようです。

Javascriptを見るとたしかにvideoと指定して送ってますね。(無駄に自分で変えてた。。。)

実はFlaskでやって一回成功していたのですが、それがこちら。

from flask import request

@app.route('/uploadVideo', methods=["POST"])
def uploadVideo():
    received = request.files
    videofile = received['video']
    videofile.save('static/received_videos/' + videofile.filename)
    return str(received), 200

videoと指定して受け取っていますね。

教訓

割とどうでもいいようなところで結構な時間を使ってしまいました。

FastAPI初めてだったのでどこが違うか色々変な方向に疑って結果回り道してました。

今後はひとつひとつ成功したところを確認すること。