Streamlitを使ってBMI計算アプリを作成しよう!

Python

今回はStreamlit、ngrok、GoogleColaboratoryを使って簡単なBMI計算のWebアプリの作り方を紹介します。
特にngrokの使い方も解説しているので、GoogleColaboratoryでStreamlitアプリを作りたい場合は参考にしてください。

BMI計算

必要なライブラリーのインストール

!pip install streamlit==1.20.0
!pip install pyngrok==4.1.1

ngrokの準備

ngrokを使うにはAPIキーが必要です。
未登録の場合は準備が必要です。

ngrokとは?

ngrokはローカルサーバーを外部公開できるツールになります。今回はGoogleコラボラトリー上で構築したチャットボットを動かすために使用します。今回使用する範囲では無料で使用ができます。

セットアップ

まずはngrokのサイトにアクセスをしてSignUpをクリックします
ngrok

alt text

必要な情報を入力して登録を進めます.

alt text

登録が完了すると次のような—ボードになります。

alt text

トークンの取得

左側のメニューのYour Authtokenをクリックしてトークンを取得します。

alt text

トークンが表示されるのでコピーします。
alt text

このトークンをGogoleColaboratoryで入力します。

!ngrok authtoken "APIキー"

もしくはdriveに.envをおいて管理する場合は、


!pip install python-dotenv
import os
from dotenv import load_dotenv

# .env ファイルのパスを指定
env_file_path = '/content/drive/MyDrive/.env'

# 指定したファイルから環境変数を読み込む
load_dotenv(env_file_path)

# APIキーを取得
ngrok_auth_token = os.getenv('NGROK_AUTH_TOKEN')

# Ngrokコマンドを実行
ngrok_command = f'ngrok authtoken "{ngrok_auth_token}"'
import subprocess
subprocess.run(ngrok_command, shell=True)

のようにできます。

BMIアプリの中身のコード

続いてアプリ部分です。

%%writefile app.py
import streamlit as st

def calculate_bmi(height, weight):
    height_m = height / 100
    bmi = weight / (height_m * height_m)
    return bmi

def categorize_bmi(bmi):
    if bmi < 18.5:
        return "低体重"
    elif 18.5 <= bmi < 24.9:
        return "正常"
    elif 24.9 <= bmi < 29.9:
        return "肥満(過体重)"
    else:
        return "高度な肥満"

def main():
    st.title("BMI 計算アプリ")
    st.write("身長と体重を入力してください。")

    height = st.number_input("身長(cm)", min_value=1, max_value=300, value=160)
    weight = st.number_input("体重(kg)", min_value=1, max_value=500, value=60)

    bmi = calculate_bmi(height, weight)
    category = categorize_bmi(bmi)

    st.write(f"あなたのBMIは {bmi:.2f} です。カテゴリー: {category}")

if __name__ == "__main__":
    main()

%%writefile app.pyは中身をapp.pyに記述するという意味になります。このapp.pyをStreamlitで起動するので、このように書きます。

内部のコードの詳細

  1. ユーザー入力の取得:
    Streamlitのst.sidebarst.text_inputst.number_inputなどを使用して、身長と体重の入力フィールドを作成します。

“`python
import streamlit as st

st.sidebar.header(“BMI 計算アプリ”)

height = st.sidebar.number_input(“身長(cm)”, min_value=1, max_value=300, value=160)
weight = st.sidebar.number_input(“体重(kg)”, min_value=1, max_value=500, value=60)
“`

  1. BMI計算:
    入力された身長と体重を使ってBMIを計算します。

python
# BMIの計算式: BMI = 体重(kg) / (身長(m) * 身長(m))
height_m = height / 100 # cmをmに変換
bmi = weight / (height_m * height_m)

  1. BMIカテゴリーの判定:
    計算されたBMI値に基づいて、BMIカテゴリーを判定し表示します。

“`python
if bmi < 18.5:
category = “低体重”
elif 18.5 <= bmi < 24.9:
category = “正常”
elif 24.9 <= bmi < 29.9:
category = “肥満(過体重)”
else:
category = “高度な肥満”

st.sidebar.info(f”BMI: {bmi:.2f} – カテゴリー: {category}”)
“`

  1. UIの表示:
    Streamlitを使って、ユーザー入力と結果を表示するシンプルなUIを構築します。

“`python
st.title(“BMI 計算アプリ”)
st.write(“身長と体重を入力してください。”)

height = st.number_input(“身長(cm)”, min_value=1, max_value=300, value=160)
weight = st.number_input(“体重(kg)”, min_value=1, max_value=500, value=60)

# BMI計算とカテゴリー判定のコードを挿入

st.write(f”あなたのBMIは {bmi:.2f} です。カテゴリー: {category}”)
“`

Streamlitの起動

Streamlitアプリを立ち上げます

!streamlit run app.py &>/dev/null&  # 「&>/dev/null&」により、出力を非表示にしてバックグランドジョブとして実行

ngrokの起動

ngrokを立ち上げてURLを取得します。

ngrok.kill()  # プロセスの修了
url = ngrok.connect(port="8501")  # 接続
if url.startswith("http://"):
    url = url.replace("http://", "https://", 1)
    print(url)

URLをクリックします。
URLクリック
すると以下のような画面になるので、
Visit

少し待ってから、Visit siteをクリックします。

少し待つのはアプリが起動するのを待つためです。
待ち時間が足りないと以下のようなエラーになりますので、再度やってみてください。
エラー発生

Failed to complete tunnel connection
The connection to https://1b10-34-85-233-83.ngrok-free.app was successfully tunneled to your ngrok client, but the client failed to establish a connection to the local address localhost:8501.

Make sure that a web service is running on localhost:8501 and that it is a valid address.

The error encountered was: dial tcp 127.0.0.1:8501: connect: connection refused

コード全体はこちら

タイトルとURLをコピーしました