この記事はLIFULL Advent Calendar 2025の記事です。(何か変なこと書いてたら私の責任です!!)
10月からLIFULL株式会社に入社して早速参加させてもらってます!
はじめに
Streamlitが便利なので使ってもらいたいなと思って記事を書きます。
早速ですが、いくつかこの記事用にStreamlitで作ったアプリを紹介します!
こんな感じで表示されるはずです。
↑は https://prettymapp.streamlit.app/ をforkして、PLATEAUデータ(高さ情報)をAPI経由で取得して既存のマップに重ねています。3Dの方はLIFULLの本社をコーポレートカラーにしてみました。
こちらはforkしたものをそのままデプロイしているだけですが、GDP Dashboardです。
シンプルだけど動的に動かせるグラフをすごく簡単に作れるのは強みだなと思ってます。
(何か日本のオープンデータで置き換えようと思ったら、前処理が大変そうで諦めました..)
Streamlitとは
↑でお見せしましたが、StreamlitはPythonのコードだけでWebのフロントエンドを自動生成してくれるPythonライブラリです。
Pythonを利用していて、API経由でデータを取得して加工したり、CSVを少し加工したものを人に見せるときに「とりあえず見た目が欲しい」とか、各々の持っているデータで試したいときにエンジニアでない方でも簡単に試す画面を用意できるのが魅力です。
最近だとLLMモデルをFine-tuningして、エンジニアでない人に試してもらう際に少しGUIをつけたところ、すごく喜んでもらえた経験があります。
そもそもStreamlitは、データサイエンティストが美しく高性能なアプリを素早く簡単に作れるようにすることを目指して、2018年に正式に創業されました。
共同創業者のAdrien Treuilleが、MLエンジニアとして機械学習のモデリング作業をしていた際、必要なツールが存在しなかったため、自分自身のために作ったのが始まりだそうです。
最初に紹介したDashboardの例でも
データ自体はこのCSVなんですが、アプリで可視化されるとパワーがありますよね。
Streamlitと他ツールの比較(主観)
Pythonフレームワークとの比較
Django
- 特徴: 認証もDBも全部入り。本格的でデカい。
- Streamlitとの違い: 本格的なアプリを作るならアリかもですが、「とりあえず手元のスクリプトをGUIにしたい」という用途には、学習コストと準備の手間(settings.py...)が大きいという印象。
Tkinter / PyQt(デスクトップアプリ)
- 特徴: Python標準でGUIが作れる。Webじゃないので配布が面倒。
- Streamlitとの違い: 相手に
.exeを渡したり、Python環境を作ってもらう必要がある。Streamlitならデプロイしてしまえば簡単にアクセスできる。
Flask / FastAPI
- 特徴: マイクロフレームワーク。APIを作るのに最適。見た目は自分で作る必要がある。
- Streamlitとの違い: UIを作るには別途HTMLテンプレートを書いたり、React/Vueを勉強する必要がある。Streamlitでデモを見せて、本格的にはFastAPIを立てて、フロントエンドはReactで、といった流れが自分は多い。
ノーコードツールとの比較(Notion, Bubbleなど)
- 特徴: プログラミング不要で手軽にアプリが作れる。非エンジニアでも使いやすい。
- Streamlitとの違い: 「複雑な計算」や「独自のデータ処理」には向いていない印象。Streamlitの強みは以下。
- Pythonでできることは何でも実現できる(Pandas、scikit-learn、LangChainなど)。ノーコードだと用意された機能の範囲内に制限され、ベンダー依存になりがち。
- Gitで管理できるので、チーム開発との相性が良い。変更履歴の追跡やレビューも通常の開発フローに乗せられる。
- 本格的なアプリへの発展が可能。Streamlitでプロトタイプを作り、ニーズが固まったら本格的な形(FastAPI + React/Remixなど)に移行しやすい。Pythonで書いているのでロジック部分の資産を活かせる。
比較まとめ
| ツール | 向いていること | 「とりあえずGUI」適性 |
|---|---|---|
| Streamlit | データの可視化・デモアプリ・社内ツール | ◎(最適・爆速) |
| Django | 大規模なWebサービス開発 | △(過剰) |
| Flask/FastAPI | APIサーバー開発 | △(UI自作の手間) |
| ノーコードツール | 定型的なアプリ・非エンジニア向け | ○(柔軟性に欠ける) |
Streamlitの使い始め
いきなりアプリから見せてしまったので、簡単であるというのを伝えるために、Pythonの環境を作るところから説明してみます。
自分はuvを使っているので、uvをインストールした前提で進めます。
# mkdir streamlit_app
# cd streamlit_app
uv init
uv add streamlit pandas
# 実行せずにそのまま書いてもいいですが、下を実行するとHello World的なアプリが生成される
# requirements.txtも生成される(上の流れからだと使わないので、この辺りスマートな方法があるかも)
# uv run streamlit init
# 既存のuvで管理されているリポジトリをクローンして動かすなら
# uv sync
これで環境が整いました。StreamlitとPandasを使える状態にしています。
import streamlit as st
import pandas as pd
import numpy as np
st.title('GUIデモ')
st.write("PythonだけでWebアプリが作れます。")
# データの作成
df = pd.DataFrame(
np.random.randn(20, 3),
columns=['a', 'b', 'c'])
# グラフの描画も1行
st.line_chart(df)
# インタラクティブなウィジェット
if st.button('ここを押してみて'):
st.balloons() # 風船が飛びます
一旦表示するだけであれば非常に直感的に書けます。
uv run streamlit run app.py
実行はこうなります。runが二つ並ぶのが少し悔しくて、uv環境のスマートな書き方があったら教えてください。
デプロイするとこれが出ます。
デプロイ
コード自体も公開していいアプリなら、Streamlit Cloudを使うのが一番簡単です。
今回載せているサンプルもStreamlit Cloudでデプロイしています。
社内向けにデプロイするならStreamlit in Snowflakeを使うのが良さそうです。
最近のアップデート
せっかくなので、2025年12月3日にリリースされた最新版(1.52.0)の新機能をいくつか紹介します。
1. st.datetime_input - 日付と時刻を一発入力
これまで日付と時刻を入力するにはst.date_inputとst.time_inputを別々に使う必要がありましたが、st.datetime_inputで1つのウィジェットにまとまりました。予約システムやスケジュール管理アプリを作るときに便利ですね。
import streamlit as st
dt = st.datetime_input("日時を選択", value=None)
st.write(f"選択された日時: {dt}")
2. st.chat_input の音声入力対応
チャット入力に音声が使えるようになりました。LLMを使ったチャットアプリに音声入力を追加したいときに、追加のライブラリなしで実現できます。
import streamlit as st
prompt = st.chat_input("メッセージを入力(または音声で)", accept_audio=True)
if prompt and prompt.audio:
st.audio(prompt.audio) # 録音した音声を再生
accept_audio=Trueにすると、チャット入力欄にマイクボタンが表示されます。録音された音声はprompt.audioで取得でき、st.audio()でそのまま再生できます。デフォルトのサンプルレートは16000Hzで、音声認識に最適化されています。
3. ボタンのキーボードショートカット
st.buttonにキーボードショートカットを設定できるようになりました。パワーユーザー向けのUIや、頻繁に使う操作へのクイックアクセスに便利です。
import streamlit as st
if st.button("実行", shortcut="Ctrl+Enter"):
st.success("実行されました!")
デモアプリ
上記の機能をまとめて試せるデモを作ってみました。
ボタンを押すと風船が飛んだり、音声で入力できたり、実際に触って体験してみてください。
Streamlitのソースコードを見てみる
どんなものか見てみようと思います。
なんの言語で書かれてる?
GitHubからも見れますが、せっかくなのでリポジトリ内で使われてる言語可視化アプリを作ってみました。
Python:TypeScript = 6:4くらいなのが特徴的ですね。
実装を軽く追ってみる
例としてst.buttonの実装を追ってみると、以下のような流れになっています。
-
Python側(バックエンド):
lib/streamlit/elements/widgets/button.pyでst.button()関数が定義されています。ここでは引数のバリデーションや、Protocol Buffersを使ったシリアライズ処理が行われます。 -
Protocol Buffers(通信定義):
proto/streamlit/proto/でPython↔JavaScript間の通信フォーマットが定義されています。labelやtype(primary/secondary/tertiary)などのフィールドがここで規定されています。 -
React側(フロントエンド):
frontend/lib/src/components/widgets/配下にReactコンポーネントがあり、Protocol Buffersでデシリアライズされたデータを受け取ってUIをレンダリングします。
PythonとReactが疎結合になっており、Protocol Buffersが両者の橋渡しをしているのが特徴的ですね。
ビルド済みのフロントエンドがPythonパッケージに同梱されているため、ユーザーはNode.jsを意識する必要がなく、Pythonだけで完結できます。その代わり、簡単にデプロイしようと思うとStreamlit Cloudなどに限られるという感じですかね。
AIエージェント向けのドキュメント整備
AGENTS.mdも用意されていました。CLAUDE.mdもありますが、中身はAGENTS.mdを参照する形になっています。
work-tmpディレクトリをAIの作業用として用意していたり、「Follow existing patterns(隣のファイルを見て既存のパターンに従え)」という指示があったりと、大規模プロジェクトでAIを活用するための工夫が見られます。
Makefileでタスクを整理しているのもいいですね。
その他
ギャラリーが充実していて、とても参考になりそうです。
少し前のPyConでお聞きしたstliteも気になっています。
最後に
久しぶりに記事を書きましたが、楽しいですね。一次情報を探しに行ったり、これはどうなんだろうと自分の知識が広がっていくのを感じました。
指摘などあったらたくさんください!
