期末專題 (三):Streamlit 打造互動式金融大屏 (第 47 章)

站主自己的課程,請大家支持
揭秘站長的架站心法:如何利用 Hugo × AI 打造高質感個人品牌網站? 揭秘站長的架站心法:如何利用 Hugo × AI 打造高質感個人品牌網站?
  • Post by
  • Jan 30, 2024
post-thumb

Streamlit 是 Python 生態系中的黑魔法。它讓你用寫 Python 腳本的方式,「畫」出一個網頁 app。對於資料科學家或後端工程師來說,這是展現成果最快的方式。

1. 建立前端應用

建立 frontend/app.py。我們需要使用 requests 來呼叫我們的 FastAPI 後端。

# frontend/app.py
import streamlit as st
import requests
import pandas as pd
import plotly.graph_objects as go

# 設定後端 API 地址
API_URL = "http://localhost:8000"

st.set_page_config(page_title="個人股票儀表板", layout="wide")
st.title("📈 Python 股票分析儀表板")

# 側邊欄:輸入股票代碼
with st.sidebar:
    st.header("設定")
    ticker = st.text_input("輸入股票代碼", value="AAPL").upper()
    period = st.selectbox("時間範圍", ["1mo", "3mo", "6mo", "1y", "5y", "max"], index=3)
    
    if st.button("分析"):
        st.session_state.search = True

# 主畫面邏輯
if st.session_state.get("search"):
    # 1. 呼叫後端 API:基本資料
    try:
        resp_info = requests.get(f"{API_URL}/stock/{ticker}")
        if resp_info.status_code == 200:
             info = resp_info.json()
             
             # 顯示 Metrics
             col1, col2, col3, col4 = st.columns(4)
             col1.metric("名稱", info['name'])
             col2.metric("現價", f"{info['price']} {info['currency']}")
             col3.metric("本益比 (P/E)", f"{info['pe_ratio']:.2f}" if info['pe_ratio'] else "N/A")
             col4.metric("EPS", info['eps'])
        else:
            st.error("找不到該股票資訊")
            st.stop()
            
        # 2. 呼叫後端 API:K 線資料
        resp_hist = requests.get(f"{API_URL}/history/{ticker}", params={"period": period})
        if resp_hist.status_code == 200:
            hist_data = resp_hist.json()
            df = pd.DataFrame(hist_data)
            
            # 轉換日期格式 (重要:plotly 需要 datetime 物件或正確字串)
            # df['Date'] is already string from API
            
            # 使用 Plotly 繪製 K 線圖
            fig = go.Figure(data=[go.Candlestick(x=df['Date'],
                            open=df['Open'],
                            high=df['High'],
                            low=df['Low'],
                            close=df['Close'])])
            
            fig.update_layout(title=f"{ticker} 股價走勢 ({period})", template="plotly_dark")
            st.plotly_chart(fig, use_container_width=True)
            
            # 顯示原始數據
            with st.expander("查看原始數據"):
                st.dataframe(df)
                
    except Exception as e:
        st.error(f"連線錯誤:{e}")

2. 執行並測試

這時候我們需要 同時 跑兩個服務:

  1. Backend: uvicorn main:app --reload (在 backend 目錄)
  2. Frontend: streamlit run app.py (在 frontend 目錄)

當你在 Streamlit 網頁輸入 “NVDA” 並按下分析,Streamlit 會發送 HTTP 請求給 FastAPI,FastAPI 去問 Yahoo,最後資料一路傳回來畫成圖表。

這就是全端開發 (Full Stack Development) 的縮影!

3. 本章重點

  • Streamlit 讓我們不用寫 HTML/Js 也能做網頁。
  • Plotly 提供了比 Matplotlib 更強大的互動式圖表 (可以縮放、滑鼠懸停)。
  • 整合力:前端與後端透過標準的 API 介面溝通,這是現代軟體架構的基石。

下一章,最後一章,我們將總結整個系列的旅程,並告訴你如何「跑起來」!


延伸閱讀

LATEST POST
TAG