TL;DR 解決
下記でファイルアップロードできます。
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}
Javascript側(送る側)
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の引数名
必要なライブラリ
下記が必要そう
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初めてだったのでどこが違うか色々変な方向に疑って結果回り道してました。
今後はひとつひとつ成功したところを確認すること。