import json import os import google.generativeai as genai import pandas as pd import requests import streamlit as st # --- 설정 --- SPEC_FILE = "static/api_spec.json" LOGO_FILE = "static/logo.png" API_SPEC_URL = "http://172.16.10.176:8888/openapi.json" # --- 도우미 함수 --- def load_api_spec(): """로컬 파일에서 API 명세를 불러옵니다.""" try: with open(SPEC_FILE, "r", encoding="utf-8") as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError) as e: st.error(f"API 명세 파일을 불러오는 중 오류 발생: {e}") return None def fetch_and_save_spec(): """URL에서 최신 API 명세를 가져와 로컬에 저장합니다.""" try: response = requests.get(API_SPEC_URL) response.raise_for_status() # 잘못된 상태 코드에 대해 예외를 발생시킵니다 spec_data = response.json() with open(SPEC_FILE, "w", encoding="utf-8") as f: json.dump(spec_data, f, indent=2, ensure_ascii=False) st.success(f"성공적으로 API 명세를 가져와 업데이트했습니다: {API_SPEC_URL}") return spec_data except requests.exceptions.RequestException as e: st.error(f"API 명세를 가져오는 데 실패했습니다: {e}") return None except json.JSONDecodeError: st.error("응답에서 JSON을 파싱하는 데 실패했습니다.") return None # --- Gemini AI 설정 --- try: api_key = os.getenv("GOOGLE_API_KEY") if not api_key: st.error( "GOOGLE_API_KEY 환경 변수가 설정되지 않았습니다. .env.chatbot 파일에서 설정해주세요." ) st.stop() genai.configure(api_key=api_key) model = genai.GenerativeModel("gemini-1.5-flash") except Exception as e: st.error(f"Gemini AI 설정 실패: {e}") st.stop() # --- Streamlit UI 설정 --- st.set_page_config( page_title="API Guide Chatbot", page_icon="🤖", layout="wide", initial_sidebar_state="expanded", ) # --- 커스텀 CSS --- st.markdown( """ """, unsafe_allow_html=True, ) # --- 메인 앱 로직 --- # 시작 시 API 명세 불러오기 api_spec = load_api_spec() # --- 사이드바 --- with st.sidebar: if os.path.exists(LOGO_FILE): st.image(LOGO_FILE, use_container_width=True) st.header("⚙️ Controls") if st.button("🔄 API 명세 새로고침"): with st.spinner("최신 API 명세를 가져오는 중..."): api_spec = fetch_and_save_spec() st.session_state.messages = [] # 새로고침 시 대화 기록 삭제 st.rerun() if api_spec: with st.expander("📘 API 상세정보 보기", expanded=True): st.info(f"**Title:** {api_spec.get('info', {}).get('title', 'N/A')}") st.text(f"Version: {api_spec.get('info', {}).get('version', 'N/A')}") paths = api_spec.get("paths", {}) if paths: endpoint_data = [] for path, methods in paths.items(): for method, details in methods.items(): endpoint_data.append( { "Method": method.upper(), "Endpoint": path, "summary": details.get("summary", "요약 없음"), } ) df = pd.DataFrame(endpoint_data) st.dataframe(df, use_container_width=True) else: st.warning("API 명세를 불러올 수 없습니다.") # --- 메인 채팅 인터페이스 --- st.markdown( "