25
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Streamlit vs PyWebIO Webフレームワーク対決!

Last updated at Posted at 2021-08-07

はじめに

概要

「PyWebIO」があればPython 100%でWebアプリ作れるってマジ!?PyWebIOを紹介したらすごくLGTMしてもらった。(ありがとうございます!)
今回はStreamlitっていうWebフレームワークとPyWebIOを比較してみたよ。

前回記事の通り、PyWebIOを使えばHTMLを一行も書かずにPython 100%でWebアプリを作れるお手軽フレームワークだよ!

Streamlitは存在だけ知ってた。
でも勝手にグラフとかを表示するデザインフレームワークだと思ってたけど…調べてみたらそんなチャチなもんじゃ断じてなかった。
Streamlitを使えばHTMLを一行も書かずにPython 100%でWebアプリを作れるお手軽フレームワークを味わったよ!

結論

とりま(やや死語)煽ってみたけど、どっちも似たような機能のフロントエンドだと思う。
特性が違うから用途に応じてお好みのものを使えばいいんじゃない?

PyWebIO

個人的な印象ではPyWebIOの方が標準オブジェクトで手厚くリッチな表現ができる。
余分な表示のない質実剛健なデザインを超速で作れるはず。
その一方で1画面にみっちり詰め込んだデザインとかを非同期処理で動かすのは苦労しそうなイメージがある。
ウィザード形式の入力画面に最適。

Streamlit

Streamlitはデータ可視化機能が豊富に用意されてる。
公式サイトで紹介されてるstreamlit helloコマンドを打つだけでアニメーションとか地図とかグラフがぐねぐね動いて「おーさむ!1」ってなること請け合い。
まだ2021年7月に出たばかりのVersion 0.84でセッション情報を扱う機能が追加されるなど、ページ遷移ロジックの定石は確立されてないようにも見える。
標準で用意されている機能が多く追加変更が早い分、凝り性の人はこだわりが多くなるかもしれない。

ちなみにSharing・Streamlitに申し込むことでHerokuやPython AnywhereのようにGithubから爆速無料でWebアプリを公開できるっぽい点も魅力的。

インストールから実行まで

ようやく本題。
2つのフレームワークを使って似たようなWebアプリを作ってみた。
簡単なアプリばかりなので出来ばえに期待はしないでほしい。

インストール

どっちもpip installでインストールできる。
ありがたい世の中だよね。

pip install streamlit
pip install pywebio

Hello, Awesome Code!

下のサンプルコードはコードが乱れているが…すまない。暑すぎて大寒なネタしか思いつかなかったんだ。

Streamlit

Streamlitのテキストはアンカーリンク付きで表示できるtitleとかコントロールが分かれて用意されてる。

さらに複数行コメントでシームレスにテキストを表示できる優れた機能もあるよ!
慣れてないとコメントアウトしたところが全文表示されたりするおちゃめ機能でもある。

import streamlit as st

st.set_page_config(page_title="Streamlit")
st.title("Titleを炊いとる")
st.header("Headerも大変だ")
st.subheader("Subtitleでサブ鯛獲る")
st.text("モルカー\nあなた好かれてるのよ。")

"""
# 他にもコメントでマークダウンできる
[st.write](https://docs.streamlit.io/en/stable/api.html#streamlit.write)で様々な様式の出力もできる、らしい。
"""

PyWebIO

タイトルとかを表示するコントロールが見つからなかった。
でもput_markdownで表現できるよ!

from pywebio.output import put_markdown, put_text
from pywebio.session import set_env

set_env(title="PyWebIO")
put_markdown("# Titleを炊いとる")
put_markdown("## Headerも大変だ")
put_markdown("### Subtitleでサブ鯛獲る")
put_text("モルカー\nあなた好かれてるのよ。")

対決!

Streamlitは最初から右上にハンバーガーが用意されててリロードとかできる。
画面読み込み中アイコンも右上に表示される。すごいね。

StreamlitのHello1StreamlitのHello2

PyWebIOはフッターが表示されるくらいで至れり尽くせり機能はなさそうだがそれが良い。
アンカーリンクとかは表示されないけどidは振られてるし、出力されるHTMLのソースはStreamlitよりも比較的素直な気がする。

PyWebIOのHello

コード実行

コード(test.pyと仮定)を保存したフォルダでそれぞれコマンドを使うと実行できる。
どっちが好みかは人それぞれ。

Streamlit

Djangoみたいに専用コマンドがある。

streamlit run .\test.py

PyWebIO

BottleとかFlaskみたいにpython実行で呼び出す。

python .\test.py

入力コントロール

※サンプルコードについて
入力コントロールを 集めて早し テーレッテレー(字余り)

Streamlit

グループボックスとか、チェックボックスのラベル表示とかのやり方が分からなかったのでそれっぽく装飾してみた。

import streamlit as st

st.title("Streamlit")
st.text_input("ねるねるねるねる", "")
st.text("ねれば")
st.checkbox("ねるほど")
st.selectbox("色が", ("変わって",))
smile = st.slider("",  min_value=1, max_value=10, value=3)
if smile != -1:
    st.error("ひっ" * smile)
st.text_area("こうやって", value="\n\n")
st.radio("うまい!", ("うまい!", "うまい!", "うまい!"))

PyWebIO

普通にコーディングするとSubmitボタンが付いてくるよ。

from pywebio.input import *
from pywebio.output import *

def show_smile(count):
    return "ひっ" * count

input_group("PyWebIO", 
    [input("ねるねるねるねる", name="neru", value=""),
     checkbox("ねれば", name="more", options=["ねるほど"]),
     select("色が", name="color", options=["変わって"]),
     slider("", name="smile", value=3, max_value=10, validate=show_smile),
     textarea("こうやって", name="koneru", rows=3, value="\n\n"),
     radio("うまい!", name="delicious", options=["うまい!", "うまい!", "うまい!"]),
    ])

対決!

Streamlitはデフォルトで凝ったデザインに見える。
PyWebIOは専有面積が狭いみたい。
笑い声はどっちもバリデーションで表現してる。

StreamlitのInputPyWebIOのInput

画面遷移

変数を保持しながら画面遷移するコードの比較だよ。
どっちのフレームワークもあんまり資料がなくて苦労したよ。

Streamlit

グローバル変数とかは最初に読み込まれるだけで、ラジオボタンを選択し直しても再読み込みしてくれないっぽい。
対策として最近できたSession State APIを使ってセッションに残したデータを遷移先でも使うコードにしてみた。
※0.84より前でも一工夫すればできる

import streamlit as st

#セッションの属性を読み書き
def show_page(voice):
    if "call_of_beauty" not in st.session_state:
        st.session_state.call_of_beauty = ""
    call = st.session_state.call_of_beauty
    call += voice
    st.session_state.call_of_beauty = call
    st.text(call)

#ページ遷移のようなもの
page = st.sidebar.radio("選択", ["ねこ", "いぬ", "てがみ"]) 
if page == "ねこ":
    show_page("にゃー")
elif page == "いぬ":
    show_page("わん")
elif page == "てがみ":
    show_page("")

PyWebIO

ラジオボタンの選択変更とかを待機する、いわゆるGUIのメインループ的な処理や非同期処理にはpywebio.pinのコントロールでpin_wait_changeする小技が必要らしい。
小技を使うとメインループで完結するからセッション使わずに変数を使いまわせるよ。
参考資料

from pywebio.pin import *
from pywebio.output import *

""" ちなみにセッションも簡単に使える
from pywebio.session import *
def show_page(voice):
    call = local.call_of_beauty or ""
    call += voice
    local.call_of_beauty = call
    return call
"""

calls = { "ねこ":"にゃー", "いぬ":"わん", "てがみ":"" }
put_radio("my_selection", label="選択", options=calls.keys(), value="ねこ")

text = ""
while True:
    new_selection = pin_wait_change(["my_selection"])
    with use_scope("my_call", clear=True):
        key = new_selection["value"]
        if key in calls:
            text += calls[key]
        put_text(text)

対決!

Streamlitはレスポンシブなサイドバーが簡単に使えるうい奴なのだ。

PyWebIOはそういうガジェットはタブしか見つからなかった。
今回はStreamlitにあわせてラジオボタンで実装してみた。

Streamlitの画面遷移PyWebIOの画面遷移

データ可視化

せっかくだから外部ツールと連携してData Virtualizationもしとく。
これをやっておくとできる!SEって感じがするからね!

matplotlibとかbokehとかnumpyのインストール方法は省略するよ。

Streamlit

標準機能でグラフ表示くらいできるし連携できるツールも幅広いみたい。
今回はすごく普通にmatplotlibと連携してサイン波を表示するサンプルにしたよ。

import matplotlib.pyplot as plt
import numpy as np
import streamlit as st

st.title("Streamlit")
st.text("サインいっこいれる")
fig = plt.figure()
xs = np.linspace(0, np.pi*4, 500)
plt.plot(xs, np.sin(xs))
st.pyplot(fig)

PyWebIO

公式サイトによると、Bokehとかpyechartsとかplotlyと連携できるらしい。
種類は多くないけど必要十分なツールと連携できるイメージ。
公式サイトのデモを見たところ、大抵のツールは出力したhtmlをput_htmlで読み取る仕組みなのかな?

今回はnotebook_typeが用意されてるBokehでサンプルを作ったよ。

import pywebio
from pywebio.output import put_text
from bokeh.io import output_notebook
from bokeh.plotting import figure, show
import numpy as np

put_markdown("# PyWebIO")
put_text("サインいっこいれる")
xs = np.arange(0, np.pi*4, 0.1)
p = figure()
p.line(xs, np.sin(xs))
output_notebook(notebook_type='pywebio')
show(p)

対決!

どっちのフレームワークもコード短いし、忠実に連携ツールを表示しててえらい!

2021-08-07 (11).png2021-08-07 (12).png

講評

この記事では本当に<br>すら書かずにWebアプリのサンプルを作っちゃった。
フレームワークのコードに癖がないとは言わないけど、そんなにフレームワーク依存のおまじないが多くないし可読性も低くないよね。

ということで、ラズパイでIoTしたデータをWebで表示したり操作したい人も、ビッグデータ分析させられて「Kibana使わずに部分的なデータだけ公開しろ」とか無茶ぶりされた人も、これらのフロントエンドを使えばハッピーエンドかもしれない。

これらのフレームワークのもたらすものはDI注入どころではなく、Py注入と言っても過言ではないのではないか!
と、今考えた造語を投げたところで筆をおかせていただきます。ありがとうございました。

  1. "Awesome!"の意。決してこの記事が大いにサムいわけではない。

25
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?