Pythonコードだけで手軽にWebシステムが作れるのでデータサイエンス業界ではかなり人気になっているStreamlit
私も簡単にデータを可視化できるので使っているのですが、今までデバッグの方法がわからず、変数などをst.writeなどで出力して変数などを確認していました。
streamlitのアプリケーションにブレークポイントを張って処理を途中で止めるなどのデバッグがしたいができるようなので、今回はVscodeでstreamlitを開発しているを想定してデバッグの設定方法を紹介したいと思います。
結論から言うと
- 拡張機能:Python Extension Packをインストール
- launch.jsonを作成してjustMyCodeをfalseに設定する
です。launch.jsonでデバッグ設定を行うことは知っていたのですがjustMyCodeをfalseにしないとブレイクポイントを設定しても止まらないということがわかるまで結構時間がかかりました。
Python Extension Packのインストール
streamlitに限らず、pythonのコードをVscodeでデバッグするために必要なPython Extension Packをインストールする必要があります。
インストールは拡張機能から検索窓でPython Extension Packと入力すれば出てきます。
インストールすると以下の拡張機能が追加されます。
- Python ※これがないとデバッグできない
- Pylance
- IntelliCode
- autoDocstring
- Jupyter
launch.jsonの作成
次にlaunch.jsonファイルを作成します。launch.jsonはVSCodeでデバッグ実行するための設定ファイルです。.vscodeフォルダ配下に作られます。
作り方はVSCodeで実行とデバッグを選択して、実行とデバッグをカスタマイズするには、launch.jsonファイルを作成しますをクリックします。
デバッガーの選択はpythonを選択します。
デバッグ構成はPython ファイルを選択します。
上記手順で行うと自動的にlaunch.jsonファイルが.vscodeフォルダの配下に作成されます。
上記設定ではstreamlitのデバッグができないので以下のように書き換えます。
{
"version": "0.2.0",
"configurations": [
{
"name": "debug",
"type": "python",
"request": "launch",
"program": "C:\\streamlit\\streamlit-sample\\Scripts\\streamlit.exe" ,
"console": "integratedTerminal",
"justMyCode": false,
"args": [
"run",
"main.py",
"--server.port",
"5678"
]
}
]
}
ポイント
“program”
“program”にはstreamlit本体が格納されているフルパスを設定します。私の場合はvenvコマンドで仮想環境を構築しているので仮想環境内のScriptsフォルダにあるstramlit.exeファイルを指定しています。
“console”
“console”は以下の3種類が設定できるみたいです。今回は“integratedTerminal”にしています。
設定値 | 説明 |
---|---|
“internalConsole” | デバッグコンソールに結果が表示される |
“integratedTerminal” | デフォルトのターミナルに結果が表示される。 デバッグ実行するたびに新しいターミナルが開かれる。 |
“externalTerminal” | 別Windowのターミナルに表示される。 |
“justMyCode”
streamlitは外部ライブラリなので外部ライブラリをデバッグできるようにするために“justMyCode”: falseにする必要があります。
justMyCodeはデフォルトではTrueなので自分のコードしかデバッグできない状態です。今回はstreamlitの機能を使うのでFalseに設定する必要があります。
これが分からなくて私はデバッグができませんでした。
“args”: []
“args”: []にはプログラムをデバッグ用にプログラムを実行したときの引数を指定できます。
今回はstreamlit コマンドに対してrunで起動してファイル名はmain.py ポートを5678で起草したいので上記のように設定しています。
上記設定をすることでデバッグ実行時に以下の引数を指定して実行するようになります。
streamlit run main.py --server.port=5678
上記設定をしてlaunch.jsonを保存すればデバッグの準備は完了です。
デバッグ用streamlitのサンプルアプリケーション
デバッグの状態が分かりやすいように簡単なstreamlitのサンプルアプリケーションを作成します。
デバッグしたいstreamlitのアプリケーションがすでに記述している場合はここは無視してください。
サンプルは,デバッグ体験ボタンを押すと名字と名前を入力すると氏名が出力される簡易的なstreamlitのプログラムです。
わかる人はわかると思いますが、1か所あえてバグが存在するように記述しています。
※あとでデバッグするため
【バグが存在するコード】
import streamlit as st
st.title("streamlit Demo App")
st.write("---")
hensu1 = st.text_input("名字を入力してください")
hensu2 = st.text_input("名前を入力してください")
#名字と名前結合する関数
def out_fullname(hensu1,hensu2):
return hensu1 + ' ' + hensu2
if st.button("デバッグ体験",type='primary',use_container_width=True):
fullname = out_fullname(hensu1,hensu2)
#バグありプログラム
if len(fullname) > 1:
st.info(fullname)
elif len(fullname) > 10:
st.error('10文字以内にしてください')
elif len(fullname) == 1:
st.error('何か入力してください')
デバッグ実行
上記でデバッグの準備は完了したので実際にデバッグ実行してみます。
ブレークポイントの設定
ブレークポイントの設定はブレークポイントを設定したい個所の左側をクリックすると設定できます。
今回は関数の部分とif分の個所にブレークポイントを張ってみました。
デバッグ実行
ブレークポイントの設定も行ったのでデバッグ実行を行います。デバッグ実行は実行とデバッグから右上の再生ボタンを押すだけでOKです。
起動が完了するとstreamlitがポート5678で起動してきます。
まずは何も入力せずにデバッグ体験ボタンを押してみます。ボタンを押すと先ほど設定したブレークポイントで止まっていることが確認できます。
左上の変数で現時点設定されている変数の値が確認できます。今回は何も入れていないので変数には何も入っていないことが確認できます。
続行ボタンを押すと次のブレークポイントで止まります。
これでデバッグ実行ができることが確認できました。
デバッグしてバグ原因を調査
実はこのプログラムは氏名の文字数が10文字以上の場合は[10文字以内にしてください]とエラー表示したいのですが10文字以上の氏名を入力してもエラーになりません。
デバッグしなくてもわかるだろーという声が聞こえてきそうですがデバッグしてみます。
ウォッチ式にlen(fullname)を入力して文字数がちゃんと取れているか確認します。
ウォッチ式を確認すると13となっているので想定通りです。なのでプログラム上ここまでは問題ないと判断できます。ということは条件文がおかしいとわかります。あなたの名前はと表示されているので
if len(fullname) > 1:
のブロックに入っていると思われます。ここまで来たらわかりますよね!最初のif分が1より大きかったら最初のif文を通るのでelif len(fullname) > 10:は通りません。
これがバグです。
このようにデバッグ実行ができると実行中のPGを自由に停止して変数などの確認ができるのでバグの特定が非常にスムーズにできます。
streamlitはpythonでプログラムを書けるので複雑なpythonコードを書くこともあると思うのでデバッグ設定をしておくと開発効率がさらに上がると思います。
この設定はstreamlitだけでなくDjangoやFastAPIなどのWebフレームワークでもう有効な設定なので理解しておいたほうが良いと思います。
コメント