🐡

dash-uploaderでアップローダを楽に実装する

2023/04/12に公開

Dashでファイルのアップロードを取り扱う

ファイルをアップロードすると、何らかの処理をしてくれて、その結果がダウンロードできるテンプレートアプリが作りたかった。よくあるdocを送るとpdfを返してくれるようなサービスで、中の処理をいろいろといじれるようなものかな。Dashでアップローダを実装する場合、dash-core-componentのUploadコンポーネントを使う方法が公式には紹介されている。

この方法はあくまでのアップロードそのものの機能しかないので、アップローダとして一般的に必要な機能、例えば

  • アップロードしたデータのパース
  • アップロードの進捗
  • 正常にアップロードされたかのチェック
  • セッション管理

といったものは都度callbackを自分で書く必要がある。
これはなかなかに面倒だが、こういった悩みはdash-uploaderというライブラリを使うことで簡単に実現できる。

https://github.com/np-8/dash-uploader

dash-uploader

アップローダのコンポーネントの定義は非常にシンプルで、

upload_box = dbc.Container([
    html.Hr(),
    html.H4("Upload with Dash-uploader"),
    du.Upload(
        id='input',
        max_file_size=1800,
        filetypes=['csv'],
        max_files=1,
        cancel_button=True,
    ),
    html.P(id='input_info'),
    html.Br(),
])

上記のように記載するだけで、

  • アップロード時の最大ファイルサイズ
  • ファイルタイプの制限
  • 1回あたりの最大アップロード数
  • アップロードの進捗
  • キャンセルボタン
  • セッション管理

を実現できる。

dash-uploaderでは基本的にセッションごとにユニークなディレクトリが生成され、ユーザがアップロードされたデータはそのディレクトリにアップロードされる。dash-uploaderのコンポーネントはプロパティとして、アップロード先のディレクトリ(upload_id)、アップロードしたファイルの名前(fileName)を持っているため、これをcallbackのInputとして用いることで、アップロードされたファイルに対して何らかの処理を行うことが可能となる。

例えば、アップロードされたファイルに対して、ファイルのバリデーションを行い、さらに別途設定されたRunボタンによって処理を走らせるcallbackは次のように実装できる。

@app.callback(
    [
        Output("input_info", "children"),
        Output("btn-run", "n_clicks"),
        Output("output", "children"),
    ],
    [
        {
            "fileNames":Input("input", "fileNames"),
            "upload_id":Input("input", "upload_id"),
            "isCompleted":Input("input", "isCompleted"),
        },
        Input("btn-run", "n_clicks"),
    ],
    prevent_inital_call=True,
)
def validation(args, n_clicks):
    is_invalid, message = validator.before_run(args)

    if is_invalid:
        return message, 0, ""
    else:
        if n_clicks > 0:
            return message, 0, logic.main(args)
        else:
            return message, 0, ""

最終的にできたテンプレートはこちら。

ファイルをアップロードすると、ファイルの有無を検知してRUNボタンが有効になる。RUNを押すと裏で処理が走り、処理が完了するとRESULTボタンが有効になり、結果がダウンロードできるようになる。めっちゃ便利!

Discussion