業界・業務から探す
導入目的・課題から探す
データ・AIについて学ぶ
News
Hakkyについて
ウェビナーコラム
◆トップ【AI・機械学習】
AI

執筆者:Handbook編集部

Streamlit Componentsについて

概要

本記事では Streamlit の Components についてイントロダクション、環境準備、使い方について解説します。 使い方の解説では、読むだけでも十分ですがハンズオン形式でも読み進めていけるような構成で作成します。

Components とは

Components は python のサードパーティーモジュールで、通常の Streamlit にはない視覚的機能やフロント、バックエンド間でのデータ連携処理等を実装できます。 独自の Component を作成してコミュニティーで共有することも出来ます。

種類

Components には三種類あります。

  • Python-only Components
    • python コードのみでコーディングした Component でカスタムした HTML/CSS を必要としない。
  • Static Components
    • python コードと埋め込み HTML/JavaScript でコーディングした Component。
  • Bidirectional Components
    • python コードと埋め込み HTML/JavaScript でコーディングした Component でフロント、バックアップエンドでデータ連携が出来る。

環境準備

Components を実装する環境を準備していきます。 準備の仕方は色々ありますが、ここでは公式のチュートリアルで公表されているやり方に倣って準備していきます。作業する際にはターミナル画面を二つ起動した状態で進めていくことをお勧めします。

まずは公式のレポジトリからcomponent-templateをクローンします。


$ git clone https://github.com/streamlit/component-template.git

クローン出来たら同じ階層で python の仮想環境を作成します。

$ cd template
$ python3 -m venv venv  # create venv
$ . venv/bin/activate   # activate venv
$ pip install streamlit # install streamlit

template フォルダに移動して Component のフロントエンドをイニシャライズします。

$ cd template/my_component/frontend
$ npm install    # Install npm dependencies
$ npm run start  # Start the Webpack dev server

もう片方のターミナル画面で Streamlit のアプリを起動します。

$ cd template
$ . venv/bin/activate  # activate the venv you created earlier
$ streamlit run my_component/__init__.py  # run the example

全て上手くいけば以下の画面が表示されるはずです。 "Click Me!"をクリックをすると"You've clicked time!"の変数部分が増加していくのが確認できると思います。

使い方

環境準備で、ボタンをクリックした分だけカウントしてくれる WEB アプリが起動できたと思います。 ここでは、その起動した WEB アプリでスクラッチで書き直していきます。 フロントエンドはmy_component/frontend/src/MyComponent.tsx、バックエンドはmy_component/__init__.pyを書き直していきます。

コードの書き換え

まずはmy_component/__init__.pyのコードを全て以下のコードに書き換えましょう。


import streamlit.components.v1 as compontents
import streamlit as st

_my_component = compontents.declare_component(
        "my_component",
        url="http://localhost:3001"
)

st.title("Component Tutorial")

def my_component(name,greeting="Streamlit",key=None):
    return _my_component(name=name, greeting=greeting, default=0, key=key)

return_value = my_component("Hello")
st.write("Number of clicks", return_value)

続いてmy_component/frontend/src/MyComponent.tsxを書き換えましょう。


import {
  Streamlit,
  StreamlitComponentBase,
  withStreamlitConnection,
} from "streamlit-component-lib"
import React, { ReactNode } from "react"

interface State {
  numClicks: number
}

/**
 * This is a React-based component template. The `render()` function is called
 * automatically when your component should be re-rendered.
 */
class MyComponent extends StreamlitComponentBase<State> {
  public state = { numClicks: 0, isFocused: false }

  public render = (): ReactNode => {
    // Arguments that are passed to the plugin in Python are accessible
    // via `this.props.args`. Here, we access the "name" arg.
    const name = this.props.args["name"]
    const greeting=this.props.args["greeting"]

    // Streamlit sends us a theme object via props that we can use to ensure
    // that our component has visuals that match the active theme in a
    // streamlit app.
    const { theme } = this.props
    const style: React.CSSProperties = {}

    // Maintain compatibility with older versions of Streamlit that don't send
    // a theme object.
    if (theme) {
      // Use the theme object to style our button border. Alternatively, the
      // theme style is defined in CSS vars.
      const borderStyling = `1px solid ${
        this.state.isFocused ? theme.primaryColor : "gray"
      }`
      style.border = borderStyling
      style.outline = borderStyling
    }

    // Show a button and some text.
    // When the button is clicked, we'll increment our "numClicks" state
    // variable, and send its new value back to Streamlit, where it'll
    // be available to the Python program.
    return (
      <span>
        <button
          style={style}
          onClick={this.onClicked}
          disabled={this.props.disabled}
        >
          Click Me!
        </button>
      </span>
    )
  }

  /** Click handler for our "Click Me!" button. */
  private onClicked = (): void => {
    // Increment state.numClicks, and pass the new value back to
    // Streamlit via `Streamlit.setComponentValue`.
    this.setState(
      prevState => ({ numClicks: prevState.numClicks + 1 }),
      () => Streamlit.setComponentValue(this.state.numClicks)
    )
  }
}

// "withStreamlitConnection" is a wrapper function. It bootstraps the
// connection between your component and the Streamlit app, and handles
// passing arguments from Python -> Component.
//
// You don't need to edit withStreamlitConnection (but you're welcome to!).
export default withStreamlitConnection(MyComponent)

ブラウザをリロードすると以下の画面が表示されると思います。

コードの解説

my_component/__init__.pyのコードを解説します。

import streamlit.components.v1 as compontents

components のモジュールをインポートしています。 これをインポートすることによって component を定義するメソッド等が呼び出せます。


_my_component = compontents.declare_component(
        "my_component",
        url="http://localhost:3001"
)

component を定義しています。 _my_component には components のオブジェクトが格納されます。引数に component の名前、アプリを起動する URL を指定します。


def my_component(name,greeting="Streamlit",key=None):
    return _my_component(name=name, greeting=greeting, default=0, key=key)

return_value = my_component("Hello")
st.write("Number of clicks", return_value)

component オブジェクトのラッパー関数my_component()を定義しています。 component の呼び出しはラッパー関数を経由するのが一般的です。 引数 key は component が識別される為に指定します。 default=0 は、初期状態ではmy_component("Hello")の返り値はnullになりますがこれを指定することによって null の代わりに 0 が返るようになります。

続いてmy_component/frontend/src/MyComponent.tsxの変更点を解説します。ここではmy_component/__init__.pyとのデータ連携部分に絞って解説します。

const name = this.props.args["name"];
const greeting = this.props.args["greeting"];

ここではmy_component/__init__.pyから変数 name、greeting を受け取っています

return (
  <span>
    <button
      style={style}
      onClick={this.onClicked}
      disabled={this.props.disabled}
    >
      Click Me!
    </button>
  </span>
);

ブラウザに返す button の HTML 要素を指定しています。 {greeting}{name}は上記の変数 name, greeting の値を HTML として埋め込んでいます。

private onClicked = (): void => {
    // Increment state.numClicks, and pass the new value back to
    // Streamlit via `Streamlit.setComponentValue`.
    this.setState(
      prevState => ({ numClicks: prevState.numClicks + 1 }),
      () => Streamlit.setComponentValue(this.state.numClicks)
    )
  }

ブラウザ上で"Click Me!"をクリックしたときにその回数をカウントするイベント処理です。 Streamlit.setComponentValue()my_component/__init__.pyで定義した component に引数の値を送信します。 この送信されたデータは変数 return_value が受け取ります。

以上が使い方の解説です。 公式のチュートリアルでは他にもスライドバー活用した component の実装方法を解説しています。 ご興味のあるかたはこちらを参照されると良いかと思います。

参考

2025年06月15日に最終更新
読み込み中...