寺田 学
目的・モチベーション
Pythonで自動化のスクリプトを作ったり、JupyterLabやColaboratoryでデータの可視化を行うことがあります。これらを作成者以外の多くの方に利用してもらう方法として、Webシステムやデスクトップアプリとして提供する方法が考えられます。
Webシステムの構築やデスクトップアプリの作成となると、技術的なハードルがあります。他には、時間的なコストに見合わないという状況もあり得ます。
Python Web UIフレームワークを使うことで、比較的少ないコードでWeb UIからスクリプトの実行や可視化をするアプリケーションを構築できます。さらにはデスクトップアプリ化することも可能です。
本記事では、PythonコードからマルチOS対応のデスクトップアプリを、Web技術を使用して作成する方法について紹介します。
全体像
本記事で取り扱う技術スタックを紹介します。
- プログラミング言語 … Python
- Python Web UIフレームワーク … Streamlit
- サーバーレス環境 … stlite / Pyodide
- デスクトップアプリ … Electron
- パッケージング・
ビルド … electron-builder
Pythonでモジュールを作り、ビルド設定をpackage.
Web UIフレームワーク
Web UIフレームワークは、Webアプリケーションのユーザーインターフェース
Python Web UIフレームワークの定義
Python Web UIフレームワークは、データサイエンスや機械学習の分野でのインタラクティブなWebアプリケーションを簡単に開発できるものとして重宝されています。Pythonコードが直接Webアプリケーションに変換されるため、フロントエンド技術の知識が少ない開発者でも簡単に使いこなすことができます。データサイエンスや機械学習の分野だけでなく、Excelや画像の加工を自動化するスクリプトなどにも簡単にGUIを提供できます。
フレームワークに準備されている関数やメソッドを使って、Pythonのモジュールを作るだけでWebアプリケーションが作れるところが魅力です。フロントエンド開発なしに、入力フォームから結果を表示するインタラクティブなWebアプリケーションを作ることができます。
Python Web UIフレームワークは、以下の特徴を持つことが一般的です。
- Pythonのコードを書くことで、フロントエンド
(HTML/ CSS/ JavaScript) コードを書かずにWeb UIが構築できる - バックエンドのAPI化やデータのシリアライズなどを意識せず、Pythonで書いたロジックを実行するWebアプリが作れる
- フォーム入力からボタンクリックで結果を表示するようなインタラクティブなWebアプリが作れる
- 可視化ライブラリとの親和性がよく、グラフ表現やさまざまな可視化ができる
Python Web UIフレームワークの種類
Python Web UIフレームワークは10種類以上あり、最近も新しいフレームワークがリリースされています。
主なものを紹介します。
ここでは、それぞれの特徴は割愛します。まずはいくつかのサイトを見ていただき、デモなどで興味がわいたものにチャレンジをしていただければと思います。
本記事では、Streamlitを使って解説します。Streamlitは、現在、Snowflakeというデータクラウド基盤サービスの会社が持つオープンソースライブラリです。
大変人気のあるWeb UIフレームワークです。さらに、@stlite/
サーバーサイドWebフレームワークとの違い
Python Web UIフレームワークは、サーバーサイドWebフレームワークとは異なる特徴を持っています。PythonのサーバーサイドWebフレームワークとしては、DjangoやFlask、FastAPIが有名です。これらのフレームワークは、Webアプリケーションを作るためのフレームワークで、データベースの操作やユーザーからのリクエストを受け取って処理を行い、結果を返すということを行います。また、HTMLやCSS、JavaScriptなどのフロントエンド技術を使って、Webページを作る必要があります。フロントエンドを作る際には、専用のテンプレートを用いたり、JavaScriptを使って動的なページを作ることがあります。
自由度が高く、複雑な処理を行うことができる一方で、開発に時間がかかることがあります。1つの入力フォームを作り、その結果を表示するだけのアプリケーションを作る場合、サーバーサイドWebフレームワークを使うのはオーバースペックです。
アプリを作る
ここからStreamlitを使ってアプリを作っています。
アプリの説明
本記事では、Excelファイルをアップロードし、2次元マトリックスを表示するアプリを作ります。
- 名称:st-matrix-chart
- 目的:Streamlitで二次元のマトリックスを表示する
- 機能:Excelのデータから列を選択し、プライオリティ・
マトリックスのような二次元可視化を行う
アップロードされたファイルをWeb画面上で確認します。ここではpandas
を活用しています。
可視化はplotly.
を使ってグラフを表示します。
完成後の画面は以下のようになります。
アップロード可能なExcelフォーマットは以下のとおりです。
「名称」
アプリに必要なファイル構成
ここでは、Streamlitで構築するWebアプリに必要な構成を説明します。次節のデスクトップアプリ化を念頭に置いたファイル構成を作ります。
必要なファイルとフォルダ構成
st-matrix-chart/
| st_matrix_chart/
| | streamlit_app.py
| package.json
| requirements.txt
パッケージ名であるst-matrix-chart
をルートとして説明します。
まず、フォルダを作ります。これはデスクトップ化に必要なものです。フォルダ名はアプリケーション名が慣例的に使われていますが、任意の名称で構いません。また、Pythonのパッケージとしてインポートできるように、英数字とアンダースコアst_
としました。
次に、st_streamlit_
モジュールを作ります。このモジュールがStreamlitのメインのモジュールとなります。なお、デスクトップアプリ化に利用するstlite
では、現状モジュール名が固定化されていますので、必ずstreamlit_
次に、package.
を空ファイルとして準備します。これはデスクトップ化に必要なファイルですので、ファイルの準備のみをしておきます。
最後に、requirements.
を準備します。これはPythonの関連パッケージを記載するファイルとなります。内容は以下のようにしてください。
streamlit
pandas
openpyxl
plotly
関連パージと用途は以下のとおりです。
環境設定
必須条件は以下のとおりです。
- Python 3.
11 (3. 8以上) - Streamlit 1.
31以上 - その他のPythonパッケージ:pandas, openpyxl, plotly
- npm or yarn
(node v18以降)
Pythonは3.
仮想環境とパッケージインストール
Pythonの標準の仮想環境venvを準備します。
% cd st-matrix-chart % python3 -m venv venv % source venv/bin/activate
Pythonパッケージをインストールします。
(venv) % pip install -r requirements.txt
ここまでで、Streamlitを使ったWebアプリの環境構築が完了しました。
アプリの構築
アプリの構築は、streamlit_
モジュールにコーディングします。今回のアプリは機能が小さいので、サブモジュールを使わずにすべて1つのモジュールで完結します。
ファイルの読み込み部分
以下のコードでExcelファイルの読み込みを行います。
pandasのDataFrame化したものを保持するためのキャッシュ機構が含まれています。
続いて、タイトルなどの表示部分と、ファイルのアップロードウィジェットを使ったファイルのアップロード機能を提供しています。
Streamlitの重要な特徴として、フォームなどの状態が変化した場合にモジュールを読み直し再実行するという点があります。画面上選択肢が変更されると、モジュールすべてが再実行され、再計算が行われます。これらを防ぐために、このモジュールの最初の①にて、再実行時にデータが失われないような工夫を行っています。
ファイルのアップロードについては、専用の機能が準備されていますので、ドラッグ&ドロップにも対応したウィジェットが設定可能です。
import streamlit as st
import pandas as pd
@st.cache_data # ① キャッシュデコレータ
def get_data(file) -> pd.DataFrame:
df = pd.read_excel(file)
return df
st.title("Excelから2次元マトリックスを表示") # ② タイトル表示
# ファイルの読み込み
st.subheader("Excelファイルをアップロードします。")
uploaded_file = st.file_uploader("Excelファイル", type="xlsx") # ③ アップロードウィジェット
コードの中で重要なポイントを説明します。
- ① :
st.
デコレータで関数の実行結果をキャッシュするようにしています。この関数では、ファイルオブジェクトからpandasのDataFrameに変換をしています。cache_ data - ② :
st.
を使ってタイトルを表示しています。Streamlitには多様な表示や機能があります。title - ③ :
st.
でファイルのアップロードウィジェットを表示しています。file_ uploader
DataFrame化
次に、アップロードされたExcelからpandasのDataFrame化を行い、表形式でデータの確認ができるようにします。
uploaded_file = st.file_uploader("Excelファイル", type="xlsx")
# ここまでは上記のコード
# DataFrame化
if uploaded_file:
df = get_data(uploaded_file) # ① ファイルからDataFrameを作る
st.write(uploaded_file.name) # ② ファイル名の表示
st.dataframe(df) # ③ 表形式で表示
コードを説明します。
- ① :キャッシュ化している
get_
関数を使ってファイルからDataFrameを作ります。data() - ② :ここではアップロードされたファイル名を表示しています。
- ③ :
st.
でDataFrameを表形式で表示します。dataframe
DataFrameの表示は以下のようになります。
可視化に使うカラムを選択
可視化に使う設定を行います。
今回の可視化は2次元のマトリックスをバブルチャートとして出力します。以下の項目をDataFrameのカラム名から選択します。
- 表示名:マウスオーバー時に表示されるオブジェクトを表す名称
(文字列) - 円の大きさ:バブルチャートの円の大きさを設定
(数値) - 色:円の色を決定
(数値) - 横軸:マトリックスのX軸
(数値) - 縦軸:マトリックスのY軸
(数値)
ここで選ばれたものが可視化ライブラリ上で要求されるデータ型になっていない場合は、ウォーニングやエラーが表示されることがあります。
st.dataframe(df)
... # ここまでは上記のコード
columns = df.columns.to_list()
name = st.selectbox("表示名", columns) # ① 表示名に使うカラムを選択
color = st.selectbox("色", columns) # ② 色でカテゴライズに使うカラムを選択
size = st.selectbox("円の大きさ", columns) # ③ 円の大きさを決めるカラムを選択
x_columns = st.selectbox("横軸", columns) # ④ 横軸のカラムを選択
y_columns = st.selectbox("縦軸", columns) # ⑤ 縦軸のカラムを選択
- ① :
st.
で表示名に使うカラムを選択します。selectbox - ② :
st.
で色を決めるカテゴライズに使うカラムを選択します。データ型が数値である必要があります。selectbox - ③ :
st.
で円の大きさに使うカラムを選択します。データ型が数値である必要があります。selectbox - ④ :
st.
で横軸selectbox (X軸) に使うカラムを選択します。データ型が数値である必要があります。 - ⑤ :
st.
で縦軸selectbox (Y軸) に使うカラムを選択します。データ型が数値である必要があります。
グラフの表示用の選択画面は以下のようになります。
可視化部分
plotly.
import plotly.express as px # インポート文を追加
...
y_columns = st.selectbox("縦軸", columns)
... # ここまでは上記のコード
if x_columns and y_columns: # ① X軸、Y軸ともに選択済みなのかを確認
if x_columns == y_columns: # ② X軸とY軸に同じカラムが選ばれていたらエラー表示
st.error("横軸と縦軸が同じです。")
else:
fig = px.scatter(
df,
x=x_columns,
y=y_columns,
size=size,
color=color,
hover_name=name,
) # ③ バブルチャートのグラフを生成
st.plotly_chart(fig) # ④ グラフを画面表示
- ① :横軸と縦軸にデータが入力されていることを確認しています。
- ② :横軸と縦軸が同じ場合は
st.
でエラーを出力しています。error - ③ :
plotly.
のexpress scatter
を使ってバブルチャートを生成しています。 - ④ :
st.
を使ってscatterオブジェクトを画面表示しています。plotly_ chart
コード全体
streamlit_
50行以下のコードで、ファイルのアップロードからアップロードデータの確認、可視化に必要な条件の設定ができ、インタラクティブなグラフを表示するアプリケーションに仕上がりました。
import streamlit as st
import pandas as pd
import plotly.express as px
@st.cache_data
def get_data(file) -> pd.DataFrame:
df = pd.read_excel(file)
return df
st.title("Excelから2次元マトリックスを表示")
# ファイルの読み込み
st.subheader("Excelファイルをアップロードします。")
uploaded_file = st.file_uploader("Excelファイル", type="xlsx")
# DataFrame化
if uploaded_file:
df = get_data(uploaded_file)
st.write(uploaded_file.name)
st.dataframe(df)
# 可視化に使うカラムを選択
columns = df.columns.to_list()
name = st.selectbox("表示名", columns)
color = st.selectbox("色", columns)
size = st.selectbox("円の大きさ", columns)
x_columns = st.selectbox("横軸", columns)
y_columns = st.selectbox("縦軸", columns)
# 可視化
if x_columns and y_columns:
if x_columns == y_columns:
st.error("横軸と縦軸が同じです。")
else:
fig = px.scatter(
df,
x=x_columns,
y=y_columns,
size=size,
color=color,
hover_name=name,
)
st.plotly_chart(fig)
PythonのWeb UIフレームワーク、およびStreamlitの良さをご理解いただけたでしょうか。
ローカル環境で実行
ローカル環境で以下のコマンドを実行すると、Streamlitのアプリが起動します。
(venv) % streamlit run st_matrix_chart/streamlit_app.py
コンソールに以下のように表示されます。
You can now view your Streamlit app in your browser. Local URL: http://localhost:8501 Network URL: http://192.168.1.122:8501
アプリの起動とともにブラウザが開いて、アプリケーションが表示されたと思います。この段階で動作の検証を行い、より自分に合ったアプリに仕上げていきましょう。
デスクトップアプリ化
デスクトップアプリ化には、@stlite/
stliteは、Pythonで書かれたStreamlitのコードをサーバーサイドまで含めてブラウザ上で実行するものです。内部では、PythonのコードをWebAssembly化するPyodideが使われています。
stliteでは、Pythonの実行環境がなくても、WebブラウザでPyodideを経由してPythonのコードが実行できます。すべてのPythonコードが実行できるというわけではありませんが、多くのライブラリがPyodideへの対応を進めています。詳細はPyodideの公式ドキュメントを確認してください。
本記事ではWebブラウザで動作することにとどまらず、OS上のデスクトップアプリ化を行います。@stlite/
Electronは、Web技術を使ってデスクトップアプリを作るためのフレームワークです。Node.
デスクトップ化の設定と環境設定
Nodeの環境を準備します。ここでは、すでに Node v20系がインストールされいる前提で進めます。
package.jsonの準備
空のファイルを準備していたpackage.
に設定を書きます。
これは、Nodeで関連パッケージのインストールを行ったり、ビルドを行うためのものです。@stlite/
{
"name": "st-matrix-chart", // ① アプリ名
"version": "0.1.0",
"homepage": "https://github.com/terapyon/st-matrix-chart", // ② URLを設定
"author": { // ③ 名前とメールアドレスを設定
"name": "Manabu TERADA",
"email": "[email protected]"
},
"main": "./build/electron/main.js",
"scripts": {
"dump": "dump-stlite-desktop-artifacts",
"serve": "cross-env NODE_ENV=production electron .",
"pack": "electron-builder --dir",
"dist": "electron-builder",
"postinstall": "electron-builder install-app-deps"
},
"build": {
"files": ["build/**/*"],
"directories": {
"buildResources": "assets"
}
},
"devDependencies": { // ④ 関連パッケージのバージョンを確認
"@stlite/desktop": "^0.52.0",
"cross-env": "^7.0.3",
"electron": "^28.2.1",
"electron-builder": "^24.9.1"
}
}
主な変更点を説明します。
- ① :nameはパッケージの名称を指定します。任意の名称に変更することができます。
- ② :homepageはパッケージのURLを指定します。リポジトリのURLでも構いません。
- ③ :authorには、nameとemailを設定します。
- ④ :devDependenciesの内容は変更は不要です。ただし、新たなバージョンが出ていることもありますので必要に応じてバージョンを上げていきます。
インストール
以下のコマンドで、必要なパッケージをインストールします。
% npm install
ビルド
ここからは、実際にデスクトップアプリをビルドしていきます。
最初にdumpを行います。これによって必要なファイル群をパッケージングしています。
% npm run dump st_matrix_chart -- -r requirements.txt
動作確認のため以下のコマンドを実行すると、ローカルでアプリが立ち上がり動作検証が行えます。動作に問題がないかを確認しましょう。
% npm run serve
以下のような画面が表示されます。
最後に、アプリケーションのビルドです。
Windows環境で以下のコマンドを実行すると、dist
フォルダにWindows用のexe
ファイルが出力されます。
> npm run dist -- --win
macOS環境で以下のコマンドを実行すると、dist
フォルダにmacOS用のdmg
ファイルが出力されます。
% npm run dist -- --mac
Linux環境で以下のコマンドを実行すると、dist
フォルダにdeb
とrpm
ファイルが出力されます。
% npm run dist -- --linux deb rpm
それぞれの環境でビルドされたパッケージをインストールし、実行することができます。出来上がったファイルを配布しインストールすることで、Pythonの実行環境がないPCでもアプリケーションを使うことができます。
なお、npm run dist
コマンドは、electron-builderコマンドラインインターフェースのエイリアスとなります
まとめ
本記事では、Streamlitで簡単にWebアプリケーションを作るところから、デスクトップアプリにビルドするところまでを駆け足で紹介しました。実際のアプリケーションを作る場合は、アイコンを設定したり細かな配慮が必要になります。また、ビルドについてもGitHub ActionsなどのCI/
今回は、Pythonのコードから簡単にデスクトップアプリができることを紹介しました。詳細は、公式ドキュメントやほかの記事などを参考に自身のアプリを作ってみていただければと思います。