Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ReactPyを使ってreact likeにUIをPythonで実装する

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for kuma127 kuma127
September 25, 2025
230

ReactPyを使ってreact likeにUIをPythonで実装する

Avatar for kuma127

kuma127

September 25, 2025
Tweet

Transcript

  1. 4

  2. 5

  3. アジェンダ • 1. ReactPyとは何か? ◦ 「フロントエンド苦手だけど、こんなのあったら便利だよね」な話 ◦ ReactPyの特徴を簡単に紹介 • 2.

    ReactPyの強みとフロントエンド構築ツールとしての位置づけ ◦ ReactPyの独自の強み ◦ ReactPyの技術的特徴 • 3. ReactPyの導入方法と実践活用 ◦ ReactPy単体での使用方法 ◦ 既存プロジェクトへの導入パターン ◦ 実装デモとコード例 7
  4. コード例 return rp.html.div( rp.html.h1("Hello ReactPy!"), rp.html.p(f"クリック回数: {count}"), rp.html.button( {"on_click": handle_click},

    "クリック" ) ) # ReactPyでのコンポーネント定義 import reactpy as rp @rp.component def HelloWorld(): count, set_count = rp.use_state(0) def handle_click(event): set_count(count + 1) 11
  5. ReactPyのメリット 1. 学習コストの削減 : JavaScript/TypeScript、JSX、Node.jsエコシステムの習得不要 2. 開発効率の向上 : フロントエンドとバックエンドを同じ言語で開発 3.

    全ての関数をサーバーサイドで実行 : onClick、useEffectなどの処理が全て Pythonランタイムで動作 4. Pythonエコシステムとの親和性 : NumPy、Pandas、scikit-learnなどのライブラ リを直接活用 14
  6. 柔軟なUIの構築 例)フィルター機能の実装 search_term, set_search_term = rp.use_state("") ## 中略 ## rp.html.input({

    "type": "text", "value": search_term, "placeholder": "商品を検索", "on_change": lambda e: set_search_term(e["target"]["value"]) # リアルタイム更新 }), 15
  7. ReactPyの特徴①: Reactのコンポーネント思想を Pythonで実現 コンポーネント思想とは: • 再利用可能な部品 : UIを独立した部品(コンポーネント)として設計 • 関心の分離

    : 各コンポーネントが独自の状態とロジックを持つ • 組み合わせによる構築 : 小さなコンポーネントを組み合わせて大きなUIを作る 17
  8. コンポーネント① @rp.component def Counter(): count, set_count = rp.use_state(0) return rp.html.div(

    rp.html.p(f"カウント: {count}"), Button("増加", lambda e: set_count(count + 1)), Button("リセット", lambda e: set_count(0)) ) # 小さなコンポーネント @rp.component def Button(text, on_click): return rp.html.button({"on_click": on_click}, text) ボタンコンポーネント カウンターコンポーネント 18
  9. コンポーネント② # 大きなアプリケーション @rp.component def App(): return rp.html.div( rp.html.h1("マイアプリ"), Counter(),

    # コンポーネントを組み合わせ Counter(), # 再利用も簡単 ) 全体コンポーネント 19
  10. Pythonならではの書き方③ スタイルの指定にPythonの辞書を利用できます @rp.component def StyledDiv(): # Pythonの辞書でスタイルや属性を指定 style = {"color":

    "blue", "font-size": "18px"} props = {"class": "my-class", "style": style} return rp.html.div(props, "スタイルされたテキスト") スタイルについては、Tailwind CSSによるデザイン適用もできます 23
  11. FastAPIを選択した場合 … FastAPIということで、Uvicorn ASGIサーバを利用してアプリケーションを実行できます。 from reactpy import component, html from

    reactpy.backend.fastapi import configure @component def HelloWorld(): return html.h1("Hello, world!") app = FastAPI() configure(app, HelloWorld) 27
  12. Python側コード from fastapi import FastAPI ## 中略 ## app =

    FastAPI() @app.get("/") async def index(): return FileResponse("index.html") # 既存のHTMLページ @component def ReactPyView(): return html.code("This text came from an ReactPy App") # 既存アプリにReactPyを追加 configure(app, ReactPyView, Options(url_prefix="/_reactpy")) 29
  13. Pythonの豊富なライブラリエコシステムとの親和性 一例 1. JupyterやPlotly-Dashとの公式統合 : データサイエンス分野での活用が明確に 意図されている 2. サーバーサイド Python実行:

    すべてのPythonライブラリが理論的に使用可能 3. データ処理と UI表示の同一環境 : NumPy、Pandas処理結果を直接UI表示 31
  14. 実用例 numpyとpandasを利用したコード例 # Pandasでデータ処理 df = pd.read_csv('./data.csv') processed_data = df.groupby('category')['sales'].mean()

    # NumPyで計算処理 statistics = { 'mean': np.mean(processed_data.values), 'std': np.std(processed_data.values) } return html.div([ html.h2("データ統計"), html.p(f"平均: {statistics['mean']:.2f}"), html.p(f"標準偏差: {statistics['std']:.2f}"), ]) 32
  15. サーバーサイドアーキテクチャ ReactPyの特徴の一つとして、全ての処理がサーバで実行されることが挙げられます。 @component def InteractiveButton(): count, set_count = use_state(0) def

    handle_click(event): # この処理はサーバーサイドで実行される print(f"クリックされました: {count}") # サーバーのターミナルに出力 set_count(count + 1) return html.button({"on_click": handle_click}, f"クリック回数: {count}") 34
  16. asyncio基盤の非同期処理 ReactPyは内部でasyncioイベントループを使用し、複数のユーザーからの同時アクセ スに対応できます: @component def AsyncComponent(): data, set_data = use_state("読み込み中...")

    async def fetch_data(): await asyncio.sleep(2) # 非同期処理もサーバーサイドで実行 set_data("データ取得完了!") use_effect(fetch_data, []) # コンポーネント初期化時に実行 return html.div(data) 36
  17. サーバーサイド実行の利点 1. Pythonエコシステムの直接活用 : サーバーサイドでNumPy、Pandas等を直接使用 2. 統一されたデバッグ環境 : Pythonデバッガーでフロントエンドロジックもデバッグ可能 3.

    セキュリティの向上 : ビジネスロジックがクライアントに露出しない 4. データベース直接アクセス : イベントハンドラ内で直接DB操作が可能 欠点としては、状態管理と処理がサーバーに集中するため、サーバへの負荷が大きいことで す。 37
  18. ReactPyにおけるVDOM実装 ReactPyは公式にVirtual Document Object Models (VDOM)を実装しており、以下の 特徴があります: • Nteract仕様準拠: NteractによるVDOM仕様に基づき、JupyterLabでも使用され

    ている実績のある仕様を採用 • JSON形式での厳密な定義 : tagName、children、attributes、eventHandlersの 構造化された辞書形式で表現 • JSON Patchによる差分更新 : JSON Patch仕様を使用した効率的な更新通信 38
  19. 状態更新フロー 1. ユーザーのインタラクション(ブラウザ) 2. イベントがWebSocket経由でサーバーに送信 3. Pythonのイベントハンドラが実行 4. set_state関数により状態更新 5.

    コンポーネントの再レンダリング 6. VDOM差分の計算 7. 変更部分のみをクライアントに送信 8. ブラウザでDOM更新 40
  20. 新規プロジェクトで導入するならば … こんなプロジェクトで活用できそうです • データ可視化ダッシュボード : Pandas/NumPyでの処理結果を直接表示 • 社内管理ツール :

    複雑なJavaScript不要でインタラクティブなUI • プロトタイプ・ MVP開発: 迅速な開発とイテレーション • 小〜中規模の Webアプリケーション : フルスタックPython開発 43
  21. @component def DataDashboard(): data = load_analysis_data() # Pandasでデータ処理 selected_period, set_period

    = use_state("monthly") filtered_data = filter_by_period(data, selected_period) コード例 45
  22. return html.div([ html.h1("売上分析ダッシュボード"), html.select({ "value": selected_period, "on_change": lambda e: set_period(e["target"]["value"])

    }, [ html.option({"value": "daily"}, "日別"), html.option({"value": "monthly"}, "月別"), ]), Chart(data=filtered_data), # データ可視化 SummaryTable(data=filtered_data) # サマリー表示 ]) 46
  23. reactpy-djangoを使った 既存Djangoプロジェクトでの活用例 {% load reactpy %} <!DOCTYPE html> <html> <body>

    {% component "demo_app.components.hello_world" recipient="World" %} <a href='/books/'>書籍一覧を見る</a> </body> </html> template.html 49
  24. データベースフックの use_query()を使う ## 中略 ## from reactpy_django.hooks import use_query async

    def get_items(): return await database_sync_to_async(SampleModel.objects.all)() @component def todo_list(): item_query = use_query(get_items) if item_query.loading: rendered_items = html.h2("Loading...") else: rendered_items = html.ul([html.li(item.text, key=item.pk) for item in item_query.data]) return html.div("Rendered items: ", rendered_items) 51
  25. 参考文献 • 公式サイト : https://reactpy.dev/ • GitHub: https://github.com/reactive-python/reactpy • Django統合:

    https://github.com/reactive-python/reactpy-django • サンプルプロジェクト : 公式リポジトリのexamplesディレクトリ 52