0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Streamlitで簡単なアプリをデプロイする

Posted at

以前から気になっていたStreamlitを勉強がてら触ってみました。
初心者の学習や簡単なモック作成をしたいような場面では、結構使えると思ったのでまとめてみました。

やること

  • Streamlitでの簡単なアプリの作成
  • Streamlit Cloudで、無料でアプリを公開する
  • テスト駆動開発

今回作るもの

今回作成したものはGithubで公開しています。
READMEに概要が記載されているので、そちらを参考にしてください。
(この記事以降も機能を追加しています)

今回はボタンを押したら、ランダムにUUIDが作成されるWEBアプリケーションを作成します。Streamlitを使ってみて、デプロイまでやってみることが目的なのでまずは難しいことはしません。

流れは下記の通りです

  1. GitHubのPublicリポジトリを作成する
  2. コードを書く
  3. GitHubにプッシュ
  4. Streamlitに公開する

さて気楽にやっていきましょう!

GitHubのpublicリポジトリを作成する

GitHubの使い方などは他の記事にお任せします。
今回は、Streamlit Cloudの無料枠でデプロイします。
そのためには、ソースコードもデプロイしたアプリも一般公開されている必要があるそうです。
有料版を使えば、もっと自由にできるらしいです。

今回私はstreamlit-mini-appsというリポジトリを作成しました。

コードを書く

現在のディレクトリはこんな感じです。

$ tree
.
├── LICENSE
└── README.md

開発に必要なディレクトリを作成します。

mkdir app test development

現状はこんな感じです。

$ tree
.
├── LICENSE
├── README.md
├── app # サービスの本体のコードを格納
├── development # 開発用のPythonの仮想環境を格納
└── test # pytestのテストコードの格納

仮想環境の作成と開発の準備

開発環境はuv推しなんですが、今回は初学者の方にも参考にさればと思いますので、Pythonに標準で搭載されているvenvを使用します。

# 仮想環境の作成
python3.13 -m venv development/venv

developmentフォルダ内にvenvというフォルダが作成されて、仮想環境関連のたくさんのファイルが作成されます。

あとは必要そうなライブラリをインストールします。

# 仮想環境の有効化する
source development/venv/bin/activate

# とりあえず、streamlitをインストールする
pip install streamlit

今後のために、ライブラリの管理もしておきましょう。

# 依存関係の保存
pip freeze > ./app/requirements.txt # appフォルダー下にrequirements.txtファイルを作成され、依存関係が記載されます。

これで、他の人も同じ環境で開発できるようになります。
個人でやっているとあまり意識しませんが、個人開発でも長期間になってくると、バージョンがズレたりPC買い替えて環境を作り直したりする必要が出てきたりするので、習慣化した方がいいです。

ちなみに、requirements.txtからライブラリをインストールする方法は下記です。

# 依存関係のインストール
pip install -r ./app/requirements.txt

Streamlitで画面を作ってみる

さて早速ですが、streamlitの画面を作成してみましょう。
まずは、画面から作成していきます。

# ファイルの作成
touch app/main.py

まずは難しいものを作るべきではないので、
ボタンを押すと"Hello World"と表示されるだけのものを作成してみます。

main.py
import streamlit as st # streamlitのインポート

# タイトルを設定
st.title("Hello, World! ボタンアプリ")

# ボタンを作成
if st.button("クリックしてHello, World!を表示"):
    # ボタンが押されたときに表示するメッセージ
    st.write("Hello, World!")

このコードで一旦、streamlitをサーバーを起動してみましょう。
起動コマンドは下記です(仮想環境をアクティブにしてください)。

streamlit run app/main.py

下記画像のように機能すればstreamlitの第一歩が完了です。
意外と簡単ですよね!

スクリーンショット 2025-01-18 13.32.13.png

関数の作成

ここからは、UUIDを作成する機能の作成に移行します。
テスト駆動開発で進めたいので、一旦ダミーの関数を作成します。

touch app/func.py # 関数作成用のファイルを作成

pip install pytest # pytestのインストール

まずは固定値を返す適当な関数を作成します。

func.py
# UUID生成アプリ
def uuid_generator(create_num):
    return "00000000-0000-0000-0000-000000000000"

次はテスト関数の作成です。

touch test/test_func.py # テスト関数作成用のファイルを作成

テストを作成します。
テストケースは下記

  • UUIDが作成されている
test_func.py
import uuid

from app.func import uuid_generator


def test_uuid_generator():
    # 関数の戻り値を取得
    result = uuid_generator()

    # 戻り値がUUIDのインスタンスであることを確認
    assert isinstance(result, uuid.UUID)

早速のテスト結果は下記です。

$ pytest
============================================================= test session starts =============================================================
platform darwin -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
rootdir: your_dir/streamlit-mini-apps
collected 1 item                                                                                                                              

test/test_func.py F                                                                                                                     [100%]

================================================================== FAILURES ===================================================================
_____________________________________________________________ test_uuid_generator _____________________________________________________________

    def test_uuid_generator():
        # 関数の戻り値を取得
        result = uuid_generator()
    
        # 戻り値がUUIDのインスタンスであることを確認
>       assert isinstance(result, uuid.UUID)
E       AssertionError: assert False
E        +  where False = isinstance('00000000-0000-0000-0000-000000000000', <class 'uuid.UUID'>)
E        +    where <class 'uuid.UUID'> = uuid.UUID

test/test_func.py:11: AssertionError
=========================================================== short test summary info ===========================================================
FAILED test/test_func.py::test_uuid_generator - AssertionError: assert False
============================================================== 1 failed in 0.03s ==============================================================

無事、エラーになりました。
コードを改修します。

func.py
import uuid


# UUID生成アプリ
def uuid_generator():
    return uuid.UUID("00000000-0000-0000-0000-000000000000")

さて、再度テストを実行します。

$ pytest
============================================================= test session starts =============================================================
platform darwin -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
rootdir: your_dir/streamlit-mini-apps
collected 1 item                                                                                                                              

test/test_func.py .                                                                                                                     [100%]

============================================================== 1 passed in 0.02s ==============================================================

無事テストをグリーンにすることができました。
しかし、現在は固定のUUIDを返しているだけなので毎回違うUUIDを返すようにしましょう。

テストケース

  • UUIDが作成されている
  • 毎回違うUUIDが生成される

テストコードを作成します。

test_func.py
import uuid

from app.func import uuid_generator

# UUIDが作成されているか
def test_uuid_generator():
    # 関数の戻り値を取得
    result = uuid_generator()

    # 戻り値がUUIDのインスタンスであることを確認
    assert isinstance(result, uuid.UUID)

# 毎回違うUUIDが生成されるか
def test_uuid_generator_generates_unique_uuids():
    # UUIDを複数回生成
    uuid1 = uuid_generator()
    uuid2 = uuid_generator()

    # それぞれが異なることを確認
    assert uuid1 != uuid2

さてテスト

$ pytest
============================================================= test session starts =============================================================
platform darwin -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
rootdir: your_dir/streamlit-mini-apps
collected 2 items                                                                                                                             

test/test_func.py .F                                                                                                                    [100%]

================================================================== FAILURES ===================================================================
_________________________________________________ test_uuid_generator_generates_unique_uuids __________________________________________________

    def test_uuid_generator_generates_unique_uuids():
        # UUIDを複数回生成
        uuid1 = uuid_generator()
        uuid2 = uuid_generator()
    
        # それぞれが異なることを確認
>       assert uuid1 != uuid2
E       AssertionError: assert UUID('00000000-0000-0000-0000-000000000000') != UUID('00000000-0000-0000-0000-000000000000')

test/test_func.py:20: AssertionError
=========================================================== short test summary info ===========================================================
FAILED test/test_func.py::test_uuid_generator_generates_unique_uuids - AssertionError: assert UUID('00000000-0000-0000-0000-000000000000') != UUID('00000000-0000-0000-0000-000000000000')
========================================================= 1 failed, 1 passed in 0.17s =========================================================

新しく追加したコードがレッドになりました。
コードを修正します。

func.py
import uuid


# UUID生成アプリ
def uuid_generator():
    return uuid.uuid4() # ここを修正
pytest
============================================================= test session starts =============================================================
platform darwin -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
rootdir: your_dir/streamlit-mini-apps
collected 2 items                                                                                                                             

test/test_func.py ..                                                                                                                    [100%]

============================================================== 2 passed in 0.04s ==============================================================

一旦グリーンになったので、streamlitの表示も変更しましょう。

main.py
import streamlit as st
from func import uuid_generator

# タイトルを設定
st.title("UUID生成アプリ")

# ボタンを作成
if st.button("UUIDを生成する"):
    # UUIDを生成
    uuid = uuid_generator()
    # UUIDを表示
    st.write(uuid)

これで作りたいものは一旦完了です。
しかし、1つだけUUIDが出てもつまらないので指定した個数出力されるように変更しましょう。

test_func.py
import uuid

from app.func import uuid_generator


# UUIDが作成されているか
def test_uuid_generator():
    # 関数の戻り値を取得
    result = uuid_generator(1)

    # 戻り値がUUIDのインスタンスであることを確認
    assert isinstance(result[0], uuid.UUID)


# 毎回違うUUIDが生成されるか
def test_uuid_generator_generates_unique_uuids():
    # UUIDを複数回生成
    uuid1 = uuid_generator(1)
    uuid2 = uuid_generator(1)

    # それぞれが異なることを確認
    assert uuid1 != uuid2


# 指定した個数のUUIDが生成されるか
def test_uuid_generator_generates_specified_number_of_uuids():
    # UUIDを生成
    uuids = uuid_generator(50)

    # 生成されたUUIDの個数が正しいことを確認
    assert len(uuids) == 50

コード

func.py
import uuid


# UUID生成アプリ
def uuid_generator(create_num):
    uuid_list = []  # UUIDを格納するリスト
    for _ in range(create_num):
        # UUIDを生成
        uuid_list.append(uuid.uuid4())
    return uuid_list

最後にStreamlitの表示を変更します。
現状はこんな感じでクールではありません。

スクリーンショット 2025-01-18 13.44.56.png

もっとクールにしましょう

main.py
import streamlit as st
from func import uuid_generator

# タイトルを設定
st.title("UUID生成アプリ")

# ユーザーからの入力を受け取る
num_uuids = st.number_input(
    "生成するUUIDの数を入力してください", min_value=1, max_value=100, value=50
)

# ボタンを作成
if st.button("UUIDを生成する"):
    # UUIDを生成
    uuids = uuid_generator(num_uuids)
    # UUIDを表示
    for uuid in uuids:
        st.write(uuid)

スクリーンショット 2025-01-18 14.00.25.png

最低限このくらいなら良いかなという感じにまとめられました。
一旦はこれでデプロイに進んでみましょう。

まずは現在作成したコードをGitHubのmain(master)にマージしておいてください。

Streamlit cloudでデプロイ!!

ここからはStreamlit cloudでの作業になります。
下記、URLからStreamlit cloudのアカウントを作成してください。
https://streamlit.io/

今回は無料枠での公開をします。

ここからはStreamlit cloudの画面なのでスクショで解説します。
GitHubでのアカウント作成するのが良いのではないと思います。

ログイン後の画面は下記のようになります。
新規アプリ作成のために、画面右上の「Creat app」をクリックしてください。

スクリーンショット 2025-01-18 14.43.37.png

下記のような画面に遷移すると思います。
今回はGitHub連携を使うので、「Deploy a public app from GitHub」の「Deploy now」をクリックしてください。

スクリーンショット 2025-01-18 14.43.46.png

GitHubの自分のアカウントと連携しておくと、下記のようにpublicリポジトリから選択することができます。

スクリーンショット 2025-01-18 14.44.02.png

Streamlitのmainのコードが書かれているファイルを選択します。

スクリーンショット 2025-01-18 14.53.39.png

ブランチ名がmainではなくmasterの場合は適宜変更してください。
またURLはある程度自らの希望で決められるので、ご自由に決めてください。

スクリーンショット 2025-01-18 14.56.49.png

全ての項目が問題なくなれば、画面下部の「Deploy」をクリックしてください。
可愛い画面に変わります。

スクリーンショット 2025-01-18 14.57.00.png

デプロイが無事完了しました。

スクリーンショット 2025-01-18 14.57.37.png

今回、アップしたアプリは下記URLから見ていただけます。
https://mini-apps-tk.streamlit.app/

まとめ

Pythonの学習をしているとUIを作ることが大変だったりして、どうしてもサービスを作ることの壁にUIが出てきてしいます。Python学習の1つの壁になってしまいます。しかし最近はPythonである程度までフロントが作れるフレームワークなども出てきています。その1つがStreamlitです。

実際にUIがあってサービスっぽくなった方が楽しいと思うので、学習を楽しくするためにもStreamlitはおすすめかなと思います。

初学者の方の参考になればと思います!

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?