Stliteを使ってAmazon S3でPythonアプリを実行!

このブログは広告を含みます。

自己紹介

こんにちは、kunioと申します。
このブログでは、主にプログラミングに関する知識や学びをシェアしつつ、子育て奮闘中に日々の生活で感じたことやちょっとした発見、興味深い話題など、雑多なテーマも自由に書いています。

  • 職業:エンジニア / プログラマー
    普段は、AWSを触ったり、業務用アプリをC#で作ったりしています。データベースはDynamoDBをよく使っています。
  • 趣味:たまに家族で旅行?に行きます。

新しい技術やアイデアに触れるたびに、感じたことや試したことをアウトプットすることで、同じように学びを深めたいと思っています。読んでくださる皆さんと気軽に情報交換できる場にできれば嬉しいです!

簡単なWeb開発ならできます。いつかご依頼いただけるように発信してゆきます これからもどうぞよろしくお願いします!

では、今回は、はStliteというフレームワークを使って、サーバーレスにStreamlitライクなWebアプリを公開する方法を試してみたいと思います。

通常のStreamlitはPythonバックエンドが常駐する形で動かしますが、StliteならWebAssembly (WASM) を使ってブラウザ側で処理が走るので、サーバー不要なホスティングが可能になるのが特徴かな。

しかも、AWSのS3バケットでWebホスティング機能を有効にすれば、ほぼ静的サイトとして公開できてしまいます。

  • まずは、完成品はこちら-iFrameでおいてみました。

ブラウザでpythonが走ってますね。。 (すみません、iPhoneで見たら、パッケージがダウンロードできない場合があるかもです)

どこにも送信しないPOSTメソッドですが、、、

なぜ、FastAPIかというと、前回まで、ゲーム開発風なAPIをFastAPIで作っていたからです。

kunio-ud-zatta.hatenablog.com

いつかは結合したいです!

2. Stliteとは?

Stliteは、StreamlitのロジックをPyodide(PythonのWASM版)上に移植し、ブラウザ内でPythonスクリプトを実行できるようにしたもので、以下のようなメリットがあります。

  • サーバーレス運用: いわゆるWebサーバーやクラウドインスタンスを用意しなくても、CDNやS3などの静的ホスティングで公開可能
  • スケール自動対応: ユーザーのブラウザ側で処理が行われるため、アクセスが増えてもサーバー負荷がほぼゼロ
  • PythonとStreamlitライクなインタラクション: 従来のStreamlitのようにUIを定義し、ボタンやグラフ、テキスト入力などを提供できる

  • 参考: github.com

なぜ、サーバレスはやはり、運用コストが下がるという点に付きますよね!!!どんどん勉強しよ。

3. 全体イメージ

  1. Stliteアプリを作成(HTML/CSS/JS + Pythonスクリプトが含まれた形で出力)
  2. S3バケットを設定して「静的ウェブサイトホスティング」を有効化
  3. 出力ファイルをS3にアップロード

4. HTML作成

<!DOCTYPE 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.58.3/build/stlite.css"
    />
  </head>
  <body>
    <div id="root"></div>
    <script src="https://cdn.jsdelivr.net/npm/@stlite/mountable@0.58.3/build/stlite.js"></script>
    <script>
      stlite.mount(
        {
          requirements: ["pandas", "numpy", "requests"],
          entrypoint: "streamlit_app.py",
          files: {
            "streamlit_app.py": `

import requests
import streamlit as st

st.title("Stlite + FastAPI Example")

username = st.text_input("Username")
if st.button("Send to server"):
    resp = requests.post("https://my-fastapi-server.com/users", json={"name": username})
    st.write("Server response:", resp.json())

`,
          },
        },
        document.getElementById("root")
      );
    </script>
  </body>
</html>
<!DOCTYPE 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.58.3/build/stlite.css"
    />
  </head>
  <body>
    <div id="root"></div>
    <script src="https://cdn.jsdelivr.net/npm/@stlite/mountable@0.58.3/build/stlite.js"></script>
    <script>
      stlite.mount(
        {
          requirements: ["pandas", "numpy", "requests"],
          entrypoint: "streamlit_app.py",
          files: {
            "streamlit_app.py": `

import requests
import streamlit as st

st.title("Stlite + FastAPI Example")

username = st.text_input("Username")
if st.button("Send to server"):
    resp = requests.post("https://my-fastapi-server.com/users", json={"name": username})
    st.write("Server response:", resp.json())

`,
          },
        },
        document.getElementById("root")
      );
    </script>
  </body>
</html>

5. S3アップロード

AWSのS3バケットを作成し、アップロードし、パブリックアクセスOnに。

python-study-ossan.s3.ap-northeast-1.amazonaws.com

6. まとめ

  • Stliteで動くアプリは、単独のHTMLファイルとして作成 → どこかにホスティング
  • ブログ記事ではiframe で埋め込む形が手軽
  • 大きなWASMファイルを読み込むため、初回ロードが重い点には注意
  • streamlitの勉強が必要。

ただ、これだけで、ブログ記事にインタラクティブPythonアプリを埋め込めるので、皆さんが実際に動くPythonデモを楽しめるようになりやすいのかな。 色々と試します。

今回も、ありがとうございました。