kines9661's picture
Upload 11 files
c1a43bf verified
"""
CLI Proxy API Plus - Streamlit Frontend for Hugging Face Spaces
Main application entry point
"""
import streamlit as st
import httpx
import os
import time
# ============================================
# 頁面配置
# ============================================
st.set_page_config(
page_title="CLI Proxy API Plus",
page_icon="🚀",
layout="wide",
initial_sidebar_state="expanded",
menu_items={
'Get Help': 'https://github.com/router-for-me/CLIProxyAPIPlus',
'Report a bug': 'https://github.com/router-for-me/CLIProxyAPIPlus/issues',
'About': """
# CLI Proxy API Plus
統一的 AI API 代理服務,支援多種 AI 提供者。
**版本**: HF Spaces Edition
"""
}
)
# ============================================
# 全局配置
# ============================================
API_BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8317")
HF_SPACE_URL = os.getenv("SPACE_URL", "")
REQUEST_TIMEOUT = 60.0
# ============================================
# 會話狀態初始化
# ============================================
if "api_status" not in st.session_state:
st.session_state.api_status = "unknown"
if "last_check" not in st.session_state:
st.session_state.last_check = 0
# ============================================
# API 狀態檢查函數
# ============================================
def check_api_status():
"""檢查 Go API 服務器狀態"""
try:
response = httpx.get(
f"{API_BASE_URL}/v1/models",
timeout=5.0
)
if response.status_code == 200:
return "online"
return "error"
except httpx.ConnectError:
return "offline"
except Exception as e:
return f"error: {str(e)}"
def get_api_health():
"""獲取 API 健康狀態詳情"""
try:
response = httpx.get(
f"{API_BASE_URL}/v0/management/health",
timeout=5.0
)
if response.status_code == 200:
return response.json()
return None
except:
return None
# ============================================
# 側邊欄
# ============================================
with st.sidebar:
# Logo 和標題
st.markdown("""
<div style="text-align: center; padding: 20px 0;">
<h1 style="font-size: 2em; margin-bottom: 0;">🚀</h1>
<h2 style="margin-top: 0;">CLI Proxy API</h2>
<p style="color: gray; font-size: 0.9em;">Plus Edition</p>
</div>
""", unsafe_allow_html=True)
st.markdown("---")
# API 狀態檢查
current_time = time.time()
if current_time - st.session_state.last_check > 30: # 30秒檢查一次
st.session_state.api_status = check_api_status()
st.session_state.last_check = current_time
status = st.session_state.api_status
if status == "online":
st.success("✅ API 服務運行中")
elif status == "offline":
st.error("❌ API 服務離線")
st.caption("請等待服務啟動...")
else:
st.warning(f"⚠️ API 狀態: {status}")
st.markdown("---")
# 導航說明
st.markdown("### 📋 功能導航")
st.markdown("""
- **💬 Chat** - API 測試介面
- **🔑 Auth** - 認證管理
- **📊 Stats** - 使用統計
- **⚙️ Settings** - 系統設定
""")
st.markdown("---")
# HF Spaces 資訊
if HF_SPACE_URL:
st.caption(f"🌐 Space: {HF_SPACE_URL}")
st.caption("📦 Hugging Face Spaces Edition")
# ============================================
# 主頁面內容
# ============================================
st.title("🚀 CLI Proxy API Plus")
st.markdown("### 統一的 AI API 代理服務")
st.markdown("""
歡迎使用 **CLI Proxy API Plus**!這是一個統一的 AI API 代理服務,
讓您可以通過標準化的 API 接口訪問多種 AI 提供者。
""")
# ============================================
# 功能卡片
# ============================================
st.markdown("## 🎯 快速開始")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.page_link("pages/1_💬_Chat.py", label="💬 API 測試", icon="💬")
st.caption("測試 API 請求和響應")
with col2:
st.page_link("pages/2_🔑_Auth.py", label="🔑 認證管理", icon="🔑")
st.caption("管理 OAuth Token")
with col3:
st.page_link("pages/3_📊_Stats.py", label="📊 使用統計", icon="📊")
st.caption("查看使用量統計")
with col4:
st.page_link("pages/4_⚙️_Settings.py", label="⚙️ 設定", icon="⚙️")
st.caption("系統配置")
st.markdown("---")
# ============================================
# 支援的提供者
# ============================================
st.markdown("## 🤖 支援的 AI 提供者")
providers = [
{"name": "Claude", "icon": "🟠", "desc": "Anthropic Claude API"},
{"name": "OpenAI", "icon": "🟢", "desc": "GPT-4, GPT-3.5"},
{"name": "Gemini", "icon": "🔵", "desc": "Google Gemini API"},
{"name": "GitHub Copilot", "icon": "⚫", "desc": "GitHub Copilot"},
{"name": "Kiro", "icon": "🟡", "desc": "AWS CodeWhisperer"},
{"name": "Codex", "icon": "🟣", "desc": "OpenAI Codex"},
]
provider_cols = st.columns(len(providers))
for i, provider in enumerate(providers):
with provider_cols[i]:
st.markdown(f"""
<div style="text-align: center; padding: 15px; border-radius: 10px; background: #f0f2f6;">
<div style="font-size: 2em;">{provider['icon']}</div>
<div style="font-weight: bold; margin-top: 5px;">{provider['name']}</div>
<div style="font-size: 0.8em; color: gray;">{provider['desc']}</div>
</div>
""", unsafe_allow_html=True)
st.markdown("---")
# ============================================
# API 端點說明
# ============================================
st.markdown("## 📡 API 端點")
st.markdown("""
| 端點 | 方法 | 說明 |
|------|------|------|
| `/v1/chat/completions` | POST | OpenAI 兼容 Chat API |
| `/v1/messages` | POST | Claude Messages API |
| `/v1/models` | GET | 列出可用模型 |
| `/v0/management/*` | * | 管理介面 API |
""")
st.markdown("---")
# ============================================
# 頁腳
# ============================================
st.markdown("""
<div style="text-align: center; padding: 20px; color: gray;">
<p>CLI Proxy API Plus - Hugging Face Spaces Edition</p>
<p>
<a href="https://github.com/router-for-me/CLIProxyAPIPlus" target="_blank">GitHub</a> |
<a href="https://huggingface.co/spaces" target="_blank">Hugging Face</a>
</p>
</div>
""", unsafe_allow_html=True)