最近、個人的に大注目のuvとReflexを紹介します。
uv
uvはPythonのプロジェクトを管理するツールです。これまで似たようなツールで、pipenv、venvを使ってきましたが、uvは一番使い心地がよく気に入っています。
Pythonのバージョン管理もできるし、ライブラリのインストールは早いし、アプリの実行のために仮想環境に入らなくてもいいしで、いいことづくめです。
Reflex
ReflexはwebアプリをPythonだけで作れる、React(JavaScript)のようなライブラリです。(実際にReactコードに変換しています)
webアプリのパーツとその状態をモジュール化できます。Pythonistのみなさんも、Pythonの関数を作るようにパーツを作って、パーツを組み合わせることでwebアプリを簡単に作れるのではないでしょうか。
今のところホットリロードが少し遅かったり、Windowsでは謎フリーズが起こったりと、フラストレーションがたまることもありますが、コンセプトは非常に面白いので今後流行っていくんじゃないかなと思っています。
グラフアプリ製作
今回はuvを使ってReflexプロジェクトを作成し、簡単なグラフアプリを作ってみたいと思います。
作るものは以下のような、ボタンを押すとYの値がランダムに変わるだけのアプリです。
あらかじめuvだけは公式サイトを見てインストールしておいてください。
まずはuvでプロジェクトを作って、プロジェクトのディレクトリに入ります。ついでに不要なhello.pyも削除しておきましょう。
uv init my-awesome-app
cd my-awesome-app/
rm hello.py
次にReflexをプロジェクトにインストールします。uvのおかげで、インストールがすごく早いです。
uv add reflex
インストールしたReflexのコマンドラインツールを使って、プロジェクトを初期化します。仮想環境をアクティブにしなくても、uvコマンドを使えばプロジェクト内にインストールされたツールを直接実行できます。
uv run reflex init
使用するテンプレートを聞かれるので、とりあえず今回は0(blank)を選んで実行しましょう。
この時点ですでにwebアプリができているので、一度動作確認をします。
uv run reflex run
すると、初回は必要なパッケージなどがインストールされるため少し時間がかかりますが、webアプリが起動します。
手元のパソコンで実行しているなら、http://localhost:3000 にアクセスするとアプリが確認できるはずです。
これだけで十分にuvとReflexの魅力は伝わったかもしれませんが、最後にPlotlyを使ったグラフアプリを作ります。
Reflexはデフォルト状態でPlotlyの描画パーツを使えますが、plotlyの関数は使えないので、uvでplotlyをインストールします。
uv add plotly
そして、my_awesome_app/my_awesome_app.pyを以下のように修正します。
import random
import reflex as rx
import plotly.graph_objects as go
class State(rx.State):
"""The app state."""
x: list[int] = [1, 2, 3, 4, 5]
y: list[float] = [random.random() for _ in range(5)]
fig: go.Figure = go.Figure(
data=go.Scatter(
x=x,
y=y,
mode='markers',
)
)
def change_y(self) -> None:
self.y = [random.random() for _ in range(5)]
self.fig = go.Figure(
data=go.Scatter(
x=self.x,
y=self.y,
mode='markers',
)
)
def index() -> rx.Component:
return rx.container(
rx.vstack(
rx.plotly(data=State.fig),
rx.button(
"Change Values",
on_click=State.change_y,
),
justify="center",
align='center',
min_height="85vh",
),
)
app = rx.App()
app.add_page(index)
注意点としては、ライブラリをつかった複雑な計算などは、rx.Stateを継承したクラス内のメソッド(今回はchange_y)に書くこと。計算した結果は、クラス変数 State.figに入れて、グラフ描画用のパーツ(rx.plotly)の引数dataに渡すことで、ユーザーが見えるような状態になります。
あとはReactのように、パーツ内の引数でレイアウトを整えて完了です。
ホットリロードがうまくいかないようでしたら、ctrl-Cで一度停止して、再度
uv run reflex run
を実行しましょう。Reflexが必要なツールを自動でインストールして、サーバーが起動します。
いかがでしたか。興味がわいた方がいらっしゃったら嬉しいです。