Spaces:
Sleeping
Sleeping
| """μ¬μ΄λλ° μ€μ λͺ¨λ. | |
| 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 | |