chainshift-dashboard / sidebar.py
GitHub Action
Sync from GitHub
ef78361
Raw
History Blame Contribute Delete
3.29 kB
"""μ‚¬μ΄λ“œλ°” μ„€μ • λͺ¨λ“ˆ.
API Key 인증 + 캠페인 선택 UI.
"""
import os
import requests
import streamlit as st
from core.api_client import ChainShiftClient
def render_sidebar() -> tuple[dict, int, str] | None:
"""μ‚¬μ΄λ“œλ°” λ Œλ”λ§.
Returns:
(auth_info, campaign_id, campaign_display) λ˜λŠ” None (인증 μ‹€νŒ¨ μ‹œ)
auth_info = {"api_key": str}
"""
with st.sidebar:
st.header("μ„€μ •")
auth_info = _render_api_key_section()
if not auth_info:
return None
st.divider()
# 캠페인 선택
result = _render_campaign_selector(auth_info)
if not result:
return None
campaign_id, campaign_display = result
return auth_info, campaign_id, campaign_display
def _render_api_key_section() -> dict | None:
"""API Key 인증 (env var μžλ™ 인증 λ˜λŠ” 직접 μž…λ ₯)."""
env_api_key = os.environ.get("CHAINSHIFT_API_KEY", "")
api_key = st.text_input(
"API Key",
type="password",
placeholder="sk_live_xxx...",
value=env_api_key,
help="API Key 직접 μž…λ ₯ (ν™˜κ²½λ³€μˆ˜ CHAINSHIFT_API_KEY 지원)",
key="direct_api_key",
)
if not api_key:
st.info("API Keyλ₯Ό μž…λ ₯ν•˜μ„Έμš”")
return None
return {
"api_key": api_key,
"access_token": None,
"email": None,
}
# =============================================================================
# Campaign selector
# =============================================================================
def _render_campaign_selector(auth_info: dict) -> tuple[int, str] | None:
"""캠페인 선택 λ“œλ‘­λ‹€μš΄."""
try:
from core.data_fetchers import get_campaigns
api_key = auth_info.get("api_key") or ""
access_token = auth_info.get("access_token") or ""
campaigns_response = get_campaigns(
api_key=api_key, access_token=access_token
)
campaigns = campaigns_response.get("data", {}).get("items", [])
if not campaigns:
st.error("μΊ νŽ˜μΈμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€")
return None
# Sort campaigns by ID descending (latest first)
campaigns_sorted = sorted(campaigns, key=lambda c: c.get("id", 0), reverse=True)
def format_campaign(c):
return f"{c['name']} (#{c['id']})"
st.markdown("**캠페인**")
selected = st.selectbox(
"캠페인 선택",
options=campaigns_sorted,
format_func=format_campaign,
label_visibility="collapsed",
)
selected_campaign_id = selected["id"]
selected_campaign_display = format_campaign(selected)
st.caption(f"Campaign #{selected_campaign_id}")
return selected_campaign_id, selected_campaign_display
except requests.exceptions.ConnectionError:
st.error("μ„œλ²„ 연결에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.")
return None
except requests.exceptions.Timeout:
st.error("μ„œλ²„ 응닡 μ‹œκ°„μ΄ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€. μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.")
return None
except Exception as e:
st.error(f"API 였λ₯˜: {str(e)}")
return None