Streamsyncを試してみる
仮想環境作成。python-3.11.5。
$ mkdir streamsync-test && cd streamsync-test
$ python -m venv .venv
$ source .venv/bin/activate
インストール
$ pip install "streamsync[ds]"
ヘルプ
$ streamsync--help
usage: streamsync [-h] [--port PORT] [--host HOST] [--enable-remote-edit] {run,edit,create,hello} [path]
Run, edit or create a Streamsync app.
positional arguments:
{run,edit,create,hello}
path Path to the app's folder
options:
-h, --help show this help message and exit
--port PORT The port on which to run the server.
--host HOST The host on which to run the server. Use 0.0.0.0 to share in your local network.
--enable-remote-edit Set this flag to allow non-local requests in edit mode.
ではサンプルを起動。3006番ポートで起動する。
$ streamsync hello
_
___| |_ ___ ___ ___ _____ ___ _ _ ___ ___
|_ -| _| _| -_| .'| |_ -| | | | _|
|___|_| |_| |___|__,|_|_|_|___|_ |_|_|___| v0.3.0
|___|
Builder is available at: http://127.0.0.1:3006
自分の場合はローカルホストではないので以下とした。
$ streamsync --host 0.0.0.0 hello
でブラウザからアクセスしてみると、"Connection rejected"。プロセスからの出力を見ると、どうやらリモートの場合は--enable-remote-edit
が必要らしい。
A session request with origin http://X.X.X.X:3006 was rejected. For security reasons, only local origins are allowed in edit mode. To circumvent this protection, use the --enable-remote-edit flag if running via command line.
$ streamsync --host 0.0.0.0 --enable-remote-edit hello
再度ブラウザからアクセスしてみる。
起動した。
モード
StreamsyncのGUIには3つのモードがある様子
- User Interface: UIを作成するモード
- Code: UIコンポーネントのアクションをコードで書く。ログも見れる。
- Preview: 実際に動かす
って感じかな
User Interface
Code
Preview
アプリケーションの作成・編集・実行
では実際にアプリケーションを作ってみる。
$ streamsync create testapp
アプリケーションのディレクトリが以下のような感じで作成される。
$ tree testapp
testapp
├── __pycache__
│ └── main.cpython-311.pyc
├── main.py
├── static
│ ├── README.md
│ └── favicon.png
└── ui.json
2 directories, 5 files
主なものは以下。
-
main.py
: アプリケーションのエントリーポイント。要はここにコードが書かれている。 -
ui.json
: UIコンポーネントの設定。 -
static/
: フロントエンドで使用する静的ファイルの置き場所
GUIエディターを起動する。ローカルホストなら以下でOK。
$ streamsync edit testapp
リモートホストの場合は最初と同様にオプションが必要。
$ streamsync edit testapp --host 0.0.0.0 --enable-remote-edit
ブラウザでアクセスしてみる。
シンプルなカウンターアプリの模様。
一旦Ctrl+Cで止める。プレビューではなく、アプリケーションとして実行してみる。
$ streamsync run testapp
リモートホストの場合はこれまで同様だけど、--enable-remote-edit
波不要。
$ streamsync edit testapp --host 0.0.0.0
アプリケーションとして起動した場合はどうやら3005番ポートになる。
App is available at: http://0.0.0.0:3005
メニューなどが一切表示されないアプリケーションとして実行される。
カウンターが動くのが確認できる。
あと、モジュールとして起動するというのがあるのだけど、ちょっとここは現時点では違いがわからない。
$ python -m streamsync.command_line run testapp --host.0.0.0
イチから作りながら学ぶ、的なチュートリアルのドキュメントがあれば良いのだけど、そういうものは見当たらないので、さっきのカウンターアプリを少し見てみる。
GUIエディタを起動
$ streamsync edit testapp --host 0.0.0.0 --enable-remote-edit
まず、UIはこうなっている。
でこのUIの構造は左のコンポーネントツリーを見るとわかる。
全部は書かないけど、こんな感じかな。
で、コンポーネントごとに属性やイベントハンドラを設定していく、という感じ。Decrementボタンにはこんな感じの設定がされている。
で処理の内容はコードを見る。
import streamsync as ss
# この文章は、あなたが書き始めたり、記憶を呼び覚ましたりするためのプレースホルダです。
# 必要に応じて削除したり、脚色したりしてください。
# ドキュメントはhttps://streamsync.cloudにあります。
# アプリの起動時にログに表示される
print("Hello world!")
# 名前が_で始まる関数は公開されない
def _update_message(state):
is_even = state["counter"] % 2 == 0
message = ("+Even" if is_even else "-Odd")
state["message"] = message
def decrement(state):
state["counter"] -= 1
_update_message(state)
def increment(state):
state["counter"] += 1
# イベントハンドラの実行時にログに表示
print(f"The counter has been incremented.")
_update_message(state)
# stateを初期化
# アンダースコアで始まる、"_my_private_element "はシリアライズされず、
# フロントエンドに送られない
initial_state = ss.init_state({
"my_app": {
"title": "My App"
},
"_my_private_element": 1337,
"message": None,
"counter": 26,
})
_update_message(initial_state)
なるほど、その名の通り、stateで状態が管理されていて、これをコンポーネントのイベントハンドラから更新するような感じっぽい。
コンポーネント側では@
を使うとstateと紐づけられるっぽいね。
コンポーネントは色々あって、ドラッグ&ドロップで配置できる。
とりあえず実際に何かを作ってみないとまだまだわからないのだけど、対Streamlitで考えると、
- Streamlitだとコンポーネントの値が変わるとページまるっと再ロードかかるけど、Streamsyncだと該当のコンポーネントだけで済みそう。
- Streamlitでレイアウトをいろいろやるのは結構しんどいイメージがあるし、だいたい同じようなインタフェースになるけど、Streamsyncのほうがデザインの自由度は多少ありそう。
あたりかな。
まだStreamsyncのコンポーネントをじっくり調べてはいないけど、Streamlitが今だとLLMのチャットフロントエンドとしても使えるように拡張されているのに対して、Streamsyncにはピンポイントでそういうコンポーネントはなさそう。データ可視化アプリ向けっていう印象が強い。
とりあえず面白そうな感じなので、自分がStreamlitで作った競馬のレース回顧可視化アプリを移植してみるかなーと思っている。