FastAPIで画像をアップロードしてダウンロードする

FastAPIを使って、画像をアップロードして、OpenCVで変換とかして、返却するというのをやりたかったのだが、イマイチな部分もある気はするけど、メモがてらに残しておく。一応、アップロードされたファイルは一旦、一時ファイルに保存している(保存しなくても良いかもしれないけど…)。そんで、process(img)の中で、画像のimgのnumpy arrayを何か変換して、戻した画像のimg_convertedのnumpy arrayを作る。あとは、img_convertedはオンメモリでcv2.imencodeで、png形式にして、Responseで返せば、画像がダウンロードされる。画像はマルチパートでアップロードする感じだけど、FastAPIのhttp://localhost:8000/docs/で送り方を確認すればよいはず。

from fastapi import FastAPI, UploadFile, File, HTTPException, Response
import cv2
import shutil
from pathlib import Path
from tempfile import NamedTemporaryFile

app = FastAPI()


@app.post("/convert/")
def convert(file: UploadFile = File(...)):
    filepath = save_upload_file_tmp(file)
    try:
        img = cv2.imread(str(filepath))
        img_converted = process(img) # OpenCVの変換処理とか
        _, img_enc = cv2.imencode('.png', img_converted)
        return Response(content=img_enc.tostring(), media_type='image/png')
    except Exception as e:
        raise HTTPException(status_code=500, detail='Failed to convert an image.')
    finally:
        filepath.unlink()


def save_upload_file_tmp(upload_file: UploadFile) -> Path:
    try:
        suffix = Path(upload_file.filename).suffix
        with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
            shutil.copyfileobj(upload_file.file, tmp)
        tmp_path = Path(tmp.name)
    finally:
        upload_file.file.close()
    return tmp_path

FastAPIでアップロードされたファイルの保存はこれを参考にした。

「FastAPIで画像をアップロードしてダウンロードする」への2件のフィードバック

  1. Fastapiの情報が非常に少ない中、貴重な内容を公開いただきありがとうございます。
    私があまりにも初学者ゆえ(初めてのAPI作成中)、フロントページからどのように画像を引っ張ってきてpythonで上記のように読ませるのかが、私の勉強不足によりわかりませんでした。

    私なりに探して以下のmultiple file uploadsの項目を参照しましたが、うまく連携できませんでした。
    https://fastapi.tiangolo.com/ja/tutorial/request-files/

    もしご教示いただけますと大変ありがたいです。

    1. マルチパートのリクエストとして、送信すれば良いので、formタグとかであれば、

      みたいな感じのフォームで送るとかだと思います。

あつし へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です