あの!!!
フロントエンドってわかりにくくないですか!!!!!
まずプログラムしてバグにぶち当たって、ものが出来上がって使える喜びを感じるの大事じゃないですか!?
なのにWebアプリ作ろうとするとHTML/CSS学んでJavaScriptの非同期処理?環境構築?
アプリって大変!!!!
もう止め!!!あきらめよう!!
となるのはもったいない
ですが実際にはデータ処理やバックエンドがメインのエンジニア、プログラム初心者にとっては覚えること、学ぶところが多すぎます。
そしてフロントエンドの世界は進化が早くなんだか色んな技術を聞きますね。
後は小さな自分だけでのツールを作るときに
ReactとかFlaskとかDjangoとか、そんなに凄いものいらなくないですか?
技術要件は適したものに当てるべきで個人の範囲で収まるならオーバースペックです。
定型文つくったりJSON書き出しツールとかね、GUI付きでぽちぽち出来たらそれでいい。
なんか大変ですよね。
あーもっともっと手軽に触り始めたい。アプリができる喜びを感じたい。
そんな時に数年前に舞い降りたのが「Streamlit(ストリームリット)」
バイバイ、フロントエンドの知識。
いつものPythonコードを数行書くだけで、最低限見栄えの良いWebアプリが爆速で完成します。一旦フロントエンド開発は置いておきましょう。
本格的なアプリを作ってみたい人におすすめな記事も書いています。興味があればこちらもご覧ください。こちらではiPhoneもAndroidもいけます。
今回紹介すること
本記事で学べる事は、Streamlitを初めて触る方向けの内容です。
- 入力フォームの作成
- 入力データの取得
- CSV、JSON、SQLite(DB)への保存
一つのサンプルアプリを作りながら解説していきます。
最後にはサンプル丸々くっつけているのでコピーしたら動きます。
完成すると、次のような入力フォームアプリを作成できるようになります。
イメージ的に業務でテストデータとかぽちぽち作るツールですね。
この記事を読む前提
今回紹介する技術を理解、実行するうえでの前提です。
アプリを作る人ならば理解できているものばかりです。
- 最低限のPC操作ができること
- コマンドプロンプトやターミナルでのコマンド操作の仕方が分かる方
- 少しだけ頑張れる方
Streamlitとは
Streamlit公式
Streamlitは、PythonだけでWebアプリケーションを作成できるオープンソースのフレームワーク。
StreamlitではPythonコードを書くだけで入力フォームやボタン、グラフ、表などを表示できるため、Web開発の知識がなくても簡単にアプリケーションを作成できます。
簡単って言ってもどれくらい簡単なのか、
例えば、テキストを表示するだけなら、次の1行で実現できます。
import streamlit as st
st.write("Hello Streamlit!")
入力フォームはこう
name = st.text_input("氏名")
たったこれだけで、ブラウザ上にテキスト入力フォームが表示されます。
これは簡単ですね!!!なんだか頑張れそうだね!!!
開発環境の準備
前提としてStreamlitをインストールする前にPythonの環境が必要です。
自身のパソコンにPythonがあるかはターミナル(またはコマンドプロンプト)で下記のコマンドから確認することが出来ます。
python --version
ここでバージョンが表示される場合はインストールは不必要です。
バージョンが表示されない場合、同じ所属の@BaspisKawaEさんの記事に分かりやすいインストール方法が記述されています。
こちらの記事の2番を参照してインストールしてください。
バージョンは3.13が推奨です。
次にStreamlitをインストールしましょう。
ターミナル(またはコマンドプロンプト)で、次のコマンドを実行します。
pip install streamlit
インストールが完了したら、正しくインストールされているか確認します。
streamlit --version
今回の記事作成時のバージョンは1.59.1で行っています。
プロジェクトを作成する
任意の場所にプロジェクトフォルダを作成します。
app.py
save.py
data
今回は、メインプログラムとして app.py を作成します。
そして保存するプログラムとして save.py を作成します。
なお、data フォルダは後半でCSV・JSON・SQLiteを保存するために使用します。
仮想環境(venv)の利用について
小規模なサンプルであれば必須ではありませんが、実際の開発では仮想環境を利用することをおすすめします。今回は利用しなくてもよいです。
ここらへんの詳しい話は書かないので下記の記事などを参考にしてください。
最初のアプリを作る
それでは、最初のStreamlitアプリを作成してみましょう。
app.py に次のコードを記述します。
import streamlit as st
st.title("はじめてのStreamlit")
st.write("こんにちは、Streamlit!")
保存したら、ターミナルで次のコマンドを実行します。
streamlit run app.py
初回起動時は、自動的にブラウザが起動し、次のような画面が表示されます。
問題なく表示出来たらこれで第一関門は突破です!
基本的な入力フォーム
それでは、実際に入力フォームを作成していきましょう。
今回作成するフォームでは、業務アプリでよく利用される入力項目を一通り実装します。
テキスト入力
最も基本的な入力フォームです。
入力された文字列は name に保存されます。
name = st.text_input(
"氏名",
placeholder="山田 太郎"
)
数値入力
テキストに代わって年齢など、数値のみ入力させたい場合
age = st.number_input(
"年齢",
min_value=0,
max_value=120,
value=20
)
ラジオボタン
よくある二者択一などの一つだけ選択するボタン、性別とかに使いますね。
gender = st.radio(
"性別",
[
"男性",
"女性",
"その他"
]
)
セレクトボックス
選択肢が多い場合はプルダウンがおすすめです。
prefecture = st.selectbox(
"都道府県",
[
"北海道",
"東京都",
"愛知県",
"大阪府",
"福岡県"
]
)
よくある表示値と入力値を別に持つタイプは下記のような感じ。
これは少しハードル高いね。
class Prefecture:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
prefecture_list = [
Prefecture(1, "北海道"),
Prefecture(13, "東京都"),
Prefecture(23, "愛知県"),
Prefecture(27, "大阪府"),
Prefecture(40, "福岡県"),
]
selected_pref = st.selectbox(
"都道府県",
options=prefecture_list,
format_func=lambda pref: pref.name
)
複数選択
複数選択を許可したい場合はこれ。
hobbies = st.multiselect(
"趣味",
[
"ゲーム",
"映画",
"旅行",
"読書",
"プログラミング"
]
)
戻り値はリスト型になります。
["ゲーム", "旅行"]
複数行入力
長文を入力したい場合。複数行入力したいときとかに使える。
profile = st.text_area(
"自己紹介",
height=120
)
スライダー
数値を直感的に入力したい場合に便利です。ちょっとリッチに見える。
score = st.slider(
"満足度",
min_value=0,
max_value=100,
value=50
)
チェックボックス
利用規約への同意などでよく利用されます。
agree = st.checkbox(
"利用規約に同意する"
)
戻り値は True または False になります。
日付入力
birthday = st.date_input(
"日付"
)
カレンダーから日付を選択できます。
ファイルアップロード
画像やCSVなどをアップロードできます。
uploaded_file = st.file_uploader(
"ファイルを選択",
type=[
"png",
"jpg",
"jpeg",
"csv"
]
)
送信ボタン
最後に送信ボタンを配置します。
submit = st.button(
"送信"
)
ボタンが押されると True が返ります。
レイアウト
入力フォームが増えてくると、縦に並べるだけでは見づらくなります。
Streamlitでは columnsや sidebarなどがあります。
少しこだわりたい場合は調べてみると良いでしょう。
他に実現できること
全て書くと大変なので下記のリファレンスを参照して下さい。
form
ここまで紹介した入力フォームは、値を変更するたびにアプリ全体が再実行されます。
複数の入力項目をまとめて送信したい場合は、st.form() を利用しましょう。
with st.form("sample_form"):
name = st.text_input("氏名")
age = st.number_input("年齢")
submit = st.form_submit_button("送信")
送信ボタンを押すまでは処理が実行されないため、入力フォームをまとめて扱いたい場合におすすめです。
入力内容をまとめて取得する
ここまで作成したフォームの入力内容は、それぞれ変数として取得できます。
例えば、入力された内容を辞書型にまとめると次のようになります。
data = {
"氏名": name,
"年齢": age,
"性別": gender,
"都道府県": prefecture,
"趣味": hobbies,
"自己紹介": profile,
"満足度": score,
"利用規約": agree,
"日付": birthday
}
辞書型にまとめておくことで、後からデータを保存したり、APIへ送信したりする処理を簡単に実装できます。
入力データを保存する
ここまでで、入力フォームを作成し、ユーザーが入力した内容を辞書型にまとめることができました。
実際の業務アプリでは、このデータをファイルやデータベースへ保存して利用します。
Pythonではさまざまな保存方法がありますが、今回は代表的な3つの方法を対象としています。
- CSV
- JSON
- SQLite
CSVもJSONもエンジニアであれば一回は見たことがある程度には当たり前のもの。
SQLiteはSQLを使いたい保存の時の例としてあげました。
いろいろ制約があるので思考停止で使うのはおすすめできませんが一例です。
なお、ここのプログラムの解説は、今回の記事の意図から外れるので書きません。興味のある方は少し調べてみましょう。
実際に動かしたサンプル
それでは最後に動かせるサンプルです。
下記のコードをapp.pyで保存しましょう
import streamlit as st
import pandas as pd
from datetime import date
from save import SaveManager
save = SaveManager()
st.set_page_config(
page_title="Streamlit 入力フォームサンプル",
layout="wide"
)
st.title("Streamlit 入力フォームサンプル")
st.write(
"""
この記事で紹介した入力フォームです。
"""
)
with st.form("user_form"):
st.header("基本情報")
col1, col2 = st.columns(2)
with col1:
name = st.text_input(
"氏名",
placeholder="山田 太郎"
)
with col2:
age = st.number_input(
"年齢",
min_value=0,
max_value=120,
value=20
)
gender = st.radio(
"性別",
[
"男性",
"女性",
"その他"
],
horizontal=True
)
prefecture = st.selectbox(
"都道府県",
[
"北海道",
"東京都",
"愛知県",
"大阪府",
"福岡県"
]
)
hobbies = st.multiselect(
"趣味",
[
"ゲーム",
"映画",
"旅行",
"読書",
"プログラミング"
]
)
profile = st.text_area(
"自己紹介",
height=120,
placeholder="自己紹介を入力してください"
)
score = st.slider(
"満足度",
0,
100,
50
)
agree = st.checkbox(
"利用規約に同意する"
)
birthday = st.date_input(
"日付",
value=date.today()
)
uploaded_file = st.file_uploader(
"ファイルアップロード",
type=[
"png",
"jpg",
"jpeg",
"csv",
"txt",
"pdf"
]
)
submitted = st.form_submit_button(
"送信"
)
if submitted:
data = {
"氏名": name,
"年齢": age,
"性別": gender,
"都道府県": prefecture,
"趣味": hobbies,
"自己紹介": profile,
"満足度": score,
"利用規約": agree,
"日付": str(birthday)
}
st.subheader("入力内容")
st.json(data)
save.save_csv(data)
save.save_json(data)
save.save_sqlite(data)
st.success("CSV・JSON・SQLiteへ保存しました。")
st.divider()
st.header("SQLite保存データ一覧")
df = save.load_sqlite()
if len(df):
st.dataframe(
df,
use_container_width=True
)
st.info(
f"登録件数:{len(df)}件"
)
else:
st.warning(
"まだデータは登録されていません。"
)
こちらはsave.pyとして保存してください。
import os
import csv
import json
import sqlite3
from datetime import datetime
import pandas as pd
class SaveManager:
"""
CSV・JSON・SQLiteの保存を管理するクラス
"""
def __init__(self):
self.data_dir = "data"
os.makedirs(self.data_dir, exist_ok=True)
self.csv_file = os.path.join(
self.data_dir,
"users.csv"
)
self.db_file = os.path.join(
self.data_dir,
"sample.db"
)
self.create_table()
# =====================================================
# SQLite 初期化
# =====================================================
def create_table(self):
conn = sqlite3.connect(self.db_file)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
氏名 TEXT,
年齢 INTEGER,
性別 TEXT,
都道府県 TEXT,
趣味 TEXT,
自己紹介 TEXT,
満足度 INTEGER,
利用規約 INTEGER,
日付 TEXT
)
""")
conn.commit()
conn.close()
def save_csv(self, data):
file_exists = os.path.exists(self.csv_file)
with open(
self.csv_file,
"a",
newline="",
encoding="utf-8-sig"
) as f:
writer = csv.writer(f)
if not file_exists:
writer.writerow([
"氏名",
"年齢",
"性別",
"都道府県",
"趣味",
"自己紹介",
"満足度",
"利用規約",
"日付"
])
writer.writerow([
data["氏名"],
data["年齢"],
data["性別"],
data["都道府県"],
",".join(data["趣味"]),
data["自己紹介"],
data["満足度"],
data["利用規約"],
data["日付"]
])
def save_json(self, data):
filename = datetime.now().strftime(
"user_%Y%m%d_%H%M%S.json"
)
path = os.path.join(
self.data_dir,
filename
)
with open(
path,
"w",
encoding="utf-8"
) as f:
json.dump(
data,
f,
ensure_ascii=False,
indent=4
)
def save_sqlite(self, data):
conn = sqlite3.connect(self.db_file)
cursor = conn.cursor()
cursor.execute("""
INSERT INTO users(
氏名,
年齢,
性別,
都道府県,
趣味,
自己紹介,
満足度,
利用規約,
日付
)
VALUES(?,?,?,?,?,?,?,?,?)
""", (
data["氏名"],
data["年齢"],
data["性別"],
data["都道府県"],
",".join(data["趣味"]),
data["自己紹介"],
data["満足度"],
int(data["利用規約"]),
data["日付"]
))
conn.commit()
conn.close()
def load_sqlite(self):
conn = sqlite3.connect(self.db_file)
df = pd.read_sql(
"SELECT * FROM users",
conn
)
conn.close()
return df
実行するときは格納ディレクトリに移動をして下記を実行します。
streamlit run app.py
うまくいくと下記のような画面が開きます。

保存結果例は下記のイメージです。

良いこと悪いこと
得意なこと(選ぶべき理由)
ちなみにここまで持ち上げてきましたが技術なので
もちろん得意なこと不得意なことが分かれています。少しまとめてみましょう。
- 「Pythonだけ」で完結する圧倒的スピード
HTML/CSS/JavaScriptの記述、APIの設計、フロントとバックエンドの連携の実装がすべて不要!
Pythonの関数を呼び出す感覚で画面が作れるため、アイデアを数時間で形にできます。
- AI・機械学習モデルのデモ画面作成
ChatGPT(LLM)のAPIを使ったチャット画面や、画像認識モデルの予測結果を表示する画面など、リッチなUIを持つAIアプリが標準コンポーネントだけでサクッと作れます。意外ですね。
向いている例
- 入力フォーム
- 売上ダッシュボード
- CSV・Excel閲覧ツール
- AIチャットアプリ
- 画像認識アプリ
- 機械学習モデルのデモ画面
- データ分析ツール
ちなみにローカル環境だけでなく、クラウドへデプロイして公開することもできます。これに関してはまた今度に記事を作ろうかとおもいます。
苦手なこと(使わない方がいいケース)
- 高度で複雑な画面遷移やデザイン
「ボタンを押したらポップアップを開いて、裏で別処理を走らせつつ、画面のここだけを書き換える」といった複雑な挙動は苦手。また、CSSを細かく当ててオリジナルのブランドデザインを作るのには向いていません。あくまでも業務ツール想定という感じ
- 大規模なWebサービス・BtoCアプリ
Streamlitは「画面を操作するたびに、Pythonスクリプトが上から下まで再実行される」という特殊な仕組みで動いています。そのため、アクセスが大量に集中する一般向けのWebサイトや、数千人が同時に使うシステムにはパフォーマンス的に向きません。
- 複雑なユーザー認証やデータベース連携
不特定多数のユーザーが会員登録し、それぞれのマイページを持つようなアプリを作る場合、Streamlit標準機能だけでは厳しく、外部サービスや別のフレームワーク(FastAPIなど)を組み合わせる必要があります。
まとめると「不特定多数向けのWebサービス、デザイン重視のサイト」は向いていません。
まとめ
この技術は自作の創作物にデータを連続で入れるツールが欲しくて手頃なのないかと探してたら見つかりました。
なんだか最新の技術がどんどん出てくるとリッチなものを使いたいと考えることが増えますが、適材適所で適度なものでいいんですね。
また、AIに〇〇を実現するWEBアプリが欲しい!とか言うと無駄に大きいもの出してくるのでこういう技術は知っておいて損はないかなと思います。
パレットリンクでは、日々のつながりや学びを大切にしながら、さまざまなお役立ち記事をお届けしています。よろしければ、ぜひ「Organization」のページもご覧ください。
また、私たちと一緒に未来をつくっていく仲間も募集中です。ご興味をお持ちの方は、ぜひお気軽にお問い合わせください。一緒に新しいご縁が生まれることを楽しみにしています。
