hanyang-chatbot / app.py
restvatikan's picture
Update app.py
8646f48 verified
raw
history blame
4.12 kB
import streamlit as st
import requests
import json
import os
# --- μ„€μ • 및 λ³΄μ•ˆ ---
# ν™˜κ²½λ³€μˆ˜ λ―Έμ„€μ • μ‹œ λΉ„λ°€λ²ˆν˜Έ 0000
st.set_page_config(page_title="ν•œμ–‘λŒ€ ν•™μΉ™ 챗봇", page_icon="🦁")
ACCESS_PASSWORD = os.getenv("APP_PASSWORD", "0000")
if "authenticated" not in st.session_state:
st.session_state.authenticated = False
def check_password():
if st.session_state.password_input == ACCESS_PASSWORD:
st.session_state.authenticated = True
del st.session_state.password_input
else:
st.error("λΉ„λ°€λ²ˆν˜Έκ°€ ν‹€λ ΈμŠ΅λ‹ˆλ‹€.")
if not st.session_state.authenticated:
st.title("πŸ”’ μ ‘κ·Ό μ œν•œ")
st.text_input("λΉ„λ°€λ²ˆν˜Έλ₯Ό μž…λ ₯ν•˜μ„Έμš”", type="password", key="password_input", on_change=check_password)
st.stop()
# --- UI κ΅¬ν˜„ ---
st.title("🦁 ν•œμ–‘λŒ€ν•™κ΅ ν•™μΉ™ 챗봇 (RAG)")
st.caption("GPT-5-mini & Real-time Hybrid Search & Reranking")
if "messages" not in st.session_state:
st.session_state.messages = []
# νžˆμŠ€ν† λ¦¬ ν‘œμ‹œ
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
if message.get("docs"):
with st.expander("μ°Έκ³  λ¬Έμ„œ (Evidence)"):
for idx, doc in enumerate(message["docs"]):
st.text(f"[{idx+1}] {doc['source']}: {doc['content']}")
# μž…λ ₯ 처리
if prompt := st.chat_input("μ§ˆλ¬Έμ„ μž…λ ₯ν•˜μ„Έμš”..."):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
# μ‹€μ‹œκ°„ μ§„ν–‰ 상황을 보여쀄 μ»¨ν…Œμ΄λ„ˆ (Gemini μŠ€νƒ€μΌ)
status_container = st.status("πŸš€ 처리 쀑...", expanded=True)
answer_placeholder = st.empty()
full_answer = ""
received_docs = []
try:
# stream=True둜 μš”μ²­ν•˜μ—¬ ν•œ 쀄씩 λ°›μŒ
response = requests.post(
"http://localhost:8000/chat", # 배포 ν™˜κ²½μ—μ„œλŠ” localhost μ‚¬μš© κ°€λŠ₯ (Docker λ‚΄λΆ€)
json={"query": prompt, "history": []},
stream=True
)
for line in response.iter_lines():
if line:
try:
data = json.loads(line.decode('utf-8'))
msg_type = data["type"]
content = data["content"]
if msg_type == "log":
# λ‘œκ·ΈλŠ” Status μ»¨ν…Œμ΄λ„ˆμ— 기둝 (흐린 글씨 효과 λŒ€μ‹  단계별 ν‘œμ‹œ)
status_container.write(content)
status_container.update(label=content) # ν˜„μž¬ 단계 제λͺ© μ—…λ°μ΄νŠΈ
elif msg_type == "answer":
# 닡변은 μ‹€μ‹œκ°„ 타이핑 효과
full_answer += content
answer_placeholder.markdown(full_answer + "β–Œ")
elif msg_type == "docs":
received_docs = content
except json.JSONDecodeError:
continue
# μ™„λ£Œ ν›„ 처리
answer_placeholder.markdown(full_answer)
status_container.update(label="βœ… 처리 μ™„λ£Œ", state="complete", expanded=False)
if received_docs:
with st.expander("μ°Έκ³  λ¬Έμ„œ"):
for idx, doc in enumerate(received_docs):
st.info(f"**{doc['source']}**: {doc['content']}")
st.session_state.messages.append({
"role": "assistant",
"content": full_answer,
"docs": received_docs
})
except Exception as e:
status_container.update(label="❌ 였λ₯˜ λ°œμƒ", state="error")
st.error(f"Connection Error: {e}")