🐍

Webブラウザ上で動くサーバーレスなStreamlitのstliteを試してみた

2023/08/29に公開

stliteとは

stliteは、Streamlitを完全にWebブラウザ上で動作させるためのものです。

stliteはPyodideというCPythonをWebAssembly/Emscriptenに移植させたモノを搭載しています。

Pyodideを使うことで、ブラウザ上でmicropipを使ってPythonパッケージをインストールして実行することができます。

言い換えれば、Streamlit用のPythonサーバーを立てることなく、静的なウェブページをセットアップするだけで、必要な計算をユーザーのマシンで直接実行することができます。

PythonでWebアプリのプロトタイプを素早く作成しデプロイしたい場合には、非常に便利なツールだと思います!

stliteを試す

edit.share.stlite.netでオンライン上でコードの編集をすることができます。

今回はstlitestlite-templateのコードを参考に、ローカルでstliteを試してみます。

ディレクトリ構造は以下の通りです。

.
├── app.py
└── index.html

index.html

今回はStreamlitの実装コード用にファイルを分けています。

以下のコードのように、<script>タグの中にstlite.mount()を記述します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <title>stlite app</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/@stlite/mountable@0.34.0/build/stlite.css"
    />
  </head>
  <body>
    <div id="root"></div>
    <script src="https://cdn.jsdelivr.net/npm/@stlite/mountable@0.34.0/build/stlite.js"></script>
    <script>
      fetch("app.py")
          .then((response) => response.text())
          .then(
              (app) => stlite.mount(
                  {
                      requirements: ["matplotlib"], // Packages to install 
                      entrypoint: "app.py",  // The target file of the `streamlit run` command
                      files: {
                          "app.py": app
                      }
                  },
                  document.getElementById("root")
              )
          );
    </script>
  </body>
</html>

app.py

Streamlitの実装コードを記述します。

今回は、matplotlibを使ってグラフを表示するコードを記述しています。

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


def main():
    st.title("Matplotlib in Streamlit")

    # データの生成
    x = np.linspace(0, 10, 100)
    y = np.sin(x)

    # プロットの作成
    fig, ax = plt.subplots()
    ax.plot(x, y, label='sin(x)')
    ax.set_title("A simple plot")
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.legend()

    # Streamlit にプロットを表示
    st.pyplot(fig)


if __name__ == "__main__":
    main()

ローカルで実行

以下のコマンドでローカルで実行します。

python3 -m http.server

実行するとHTTPサーバーが立ち上がります。

✗ python3 -m http.server
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
::1 - - [28/Aug/2023 23:51:52] "GET / HTTP/1.1" 200 -
::1 - - [28/Aug/2023 23:51:53] "GET /app.py HTTP/1.1" 200 -

10〜20秒ほどローディングをします。

描画されました!

Discussion