Open10

Plotly-Dash備忘録

でんちゅーでんちゅー

Including Local CSS and JavaScript

  • /assets/という名称のディレクトリに格納している以下のファイルは自動的にローディングされる
    • .cssで終わるcssファイル
    • .jsで終わるjsファイル
    • favicon.icoという名称のファイル
  • アルファベット順に読み込まれるので、順番を指定したければ10_typography.cssのように数字を先頭に付ける
  • /assets/を読み込むには、Dashのコンストラクタで__name__を指定する必要がある

https://dash.plotly.com/external-resources

でんちゅーでんちゅー

Persistence(永続性)

  • 永続性:dash-tableでサポートされているもので、前回指定したフィルタ条件等を次回以降アクセス時も保持しておくような機能

  • 以下の3種類のPersistenceを指定することが可能

    • memory:メモリ保存
      • ページ更新時にリセットされる
      • タブ切り替え時には保持され、リロード時にはリセット
  • local:window.localStorageを使用

    • そのコンピュータのそのブラウザ内で無期限にデータが保持される
  • session:window.localStorageを使用

    • ページリロード時はデータを保持
    • ブラウザを閉じるか新しいブラウザのタブで開くとリセット

https://dash.plotly.com/persistence

でんちゅーでんちゅー

Dash Dev Tools

  • Dashアプリの開発時に有効なツールで、デバッグと開発を快適にするためのもの
  • 以下の機能が存在している
    • コールバックグラフ
      • コールバックがどのような順序で実行され、どれくらいの時間がかかり、どのようなデータがウェブブラウザのDashアプリとPythonコードの間でやり取りされるかを表示する
    • コード再読み込み
    • ホットリロード
    • アプリ内エラーレポート
    • コンポーネント検証
  • これらの機能はrunでdebug=Trueのときにオンになる

https://dash.plotly.com/devtools

でんちゅーでんちゅー

Loading States

  • dash_core_componentsまたはdash_html_componentsの全てのコンポーネントにはloading_stateプロパティがある
  • ここにはコンポーネントがロード中かどうかを示すis_loadingプロパティが含まれる
  • component_nameprop_name属性はそのコンポーネントの名前とロード中のプロパティの名前(=layout)を返す
  • このプロパティによって、コンポーネントがロード中である場合の挙動を定義することが可能
  • 代表的な使用方法でいうとコンポーネントがロード中にローディングスピナーを表示しておく等の処理が挙げられる

https://dash.plotly.com/loading-states

でんちゅーでんちゅー

Dash Testing

  • dash.testingではカスタムpytest-fixtureとユニットテストとエンドツーエンドテストのためのテストAPIを提供している
  • 以下のコマンドでinstallできる
py -m pip install dash[testing]

Unit Tests

  • dash.testingはコールバックのユニットテストをサポートしている

Mocking Callback Context

  • コールバックをテストするにはcallback_contextをモックする必要がある
  • callback_contextのモックには以下のimportが必要
from contextvars import copy_context
from dash._callback_context import context_value
from dash._utils import AttributeDict

End-to-End Tests

  • dash.testingはEnd-to-Endのテストもサポートしている
  • Selenium Gridお使ってテストを実行する場合はWebDriverをインストールする必要がある

https://dash.plotly.com/testing

でんちゅーでんちゅー

Dash App Life Cycle

  • py -m app.pyまたはgunicornn app:serverが実行されると、Dashアプリ内の全てのファイルが実行される。
  • pd.read_csvのような処理はプログラム開始時に実行されるため、csvに変更があった場合は再起動するまで反映されない
  • この場合、定期的なタスクでデータを提供するか、app.layoutをロードごとにレイアウトを再生成する関数として設定することが有効

https://dash.plotly.com/app-lifecycle

でんちゅーでんちゅー

Use Tailwindcss in Dash

  • Dashコンストラクタのexternal_scripts引数にTailwind-cdnのURLをリスト形式で渡すことで使用可能になる
app = Dash(
    __name__,
    # use_pages=True,
    external_scripts=["https://tailwindcss.com/", {"src": "https://cdn.tailwindcss.com"}]
)
でんちゅーでんちゅー

ディレクトリ構成の作成

ここでは、dashでMPA(Multi Page Application)を作成することを想定して、筆者がよく使っているディレクトリ構成を作成していく。

dash-id-sandbox/
├── README.md
├── app.py
├── assets/
│   ├── custom.css   # 必要に応じて
│   └── custom.js   # 必要に応じて
├── pages/
│   ├── __init__.py
│   ├── page.py
│   ├── content1/
│   │   ├── _components/
│   │   ├── _usecases/
│   │   ├── __init__.py
│   │   └── page.py
│   └── content2/
│       ├── _components/
│       ├── _usecases/
│       ├── __init__.py
│       └── page.py
├── components/
│   ├── __init__.py
│   ├── component1.py
│   └── ...
├── usecases/
│   ├── __init__.py
│   ├── usecase1.py
│   └── ...
├── utils/
│   ├── util1.py
└── tests/
    ├── __init__.py
    ├── conftest.py
    ├── test_app.py
    └── ...
# /で終わるものはディレクトリを表す.

1層目のディレクトリ構成

先ほどの図はディレクトリ構成図の全体像だったが、数が多くて見づらいため、まずは第1層から見ていこう。
dash-id-sandbox(ルート)ディレクトリ直下だけを抜き出したのが以下の図である.

dash-id-sandbox/
├── README.md
├── app.py
├── assets/
├── pages/
├── components/
├── usecases/
├── utils/
└── tests/
# /で終わるものはディレクトリを表す.

各ディレクトリ/ファイルについての詳細は以下の通り.

名称 type 詳細
README.md .md いわゆるREADME。プロジェクトの起動方法等を記述する。
app.py .py dashアプリケーションのエントリーポイント(アプリ自体の設定や起動コード)を記述する。
assets directory カスタムCSSファイルやJSファイル等を格納する。dashアプリケーション内から参照する画像ファイル等もここに入れる。
pages directory MPA(Multi Page Application)を作成する際に使用する、ページ別ファイルを格納するためのディレクトリ。pagesという名前じゃないとエラー吐くので注意。
components directory ヘッダーやフッター等のグローバルコンポーネントを格納するためのディレクトリ。
usecases directory components内のcallbackが呼び出すためのロジック関数を格納するためのディレクトリ。
utils directory util関数等を格納するためのディレクトリ。カスタムロギングモジュール等を入れる
tests directory テストコードを格納するためのディレクトリ。

2層目以降(pages内)の特筆すべきディレクトリ構成

次に、2層目以降のうち特徴的であるpagesディレクトリ内の構成について抜き出して見ていく。
pagesディレクトリ直下だけを抜き出したのが以下の図である.

├── pages/
│   ├── __init__.py
│   ├── page.py
│   ├── content1/
│   │   ├── _components/
│   │   ├── _usecases/
│   │   ├── __init__.py
│   │   └── page.py
│   └── ...
# /で終わるものはディレクトリを表す.

各ディレクトリ/ファイルについての詳細は以下の通り.

名称 type 詳細
_init_.py .py Python3.3以降は必須でないが、今回使用するため記述している。
page.py .py URLパスにおけるルート(/)のページファイル。
content1 directory URLパスにおける/content1のページに関連するファイルを格納するディレクトリ。
_components directory content1ページのみで使用されるローカルコンポーネントを格納するディレクトリ
_usecases directory content1のローカルコンポーネント_components内のcallbackが呼び出すためのロジック関数を格納するためのディレクトリ
page.py .py content1ページのページファイル