Spaces:
Sleeping
Sleeping
key 방식 수정
Browse files- RAG챗봇_배포.py +31 -32
RAG챗봇_배포.py
CHANGED
|
@@ -29,25 +29,23 @@
|
|
| 29 |
처음 한 번만 아래 명령으로 필요한 패키지를 설치합니다.
|
| 30 |
(가상환경(venv) 안에서 실행하는 것을 권장합니다.)
|
| 31 |
|
| 32 |
-
pip install streamlit google-generativeai chromadb
|
| 33 |
|
| 34 |
또는 `requirements.txt` 파일에 다음을 적어두고 한 번에 설치할 수도 있습니다.
|
| 35 |
|
| 36 |
streamlit
|
| 37 |
google-generativeai
|
| 38 |
chromadb
|
| 39 |
-
python-dotenv
|
| 40 |
|
| 41 |
→ pip install -r requirements.txt
|
| 42 |
|
| 43 |
[실행 방법]
|
| 44 |
-
1)
|
| 45 |
-
|
| 46 |
-
2) 사전 빌드된 `chroma_election_db/` 폴더가 같은 경로에 있는지 확인합니다.
|
| 47 |
-
3) 아래 명령으로 앱을 띄웁니다(파이썬 직접 실행이 아니라 `streamlit run` 사용!).
|
| 48 |
|
| 49 |
streamlit run RAG챗봇_배포.py
|
| 50 |
|
|
|
|
| 51 |
브라우저가 자동으로 열리지 않으면 터미널에 표시된 http://localhost:8501 로 접속하세요.
|
| 52 |
=====================================================================
|
| 53 |
"""
|
|
@@ -55,20 +53,12 @@
|
|
| 55 |
# ─────────────────────────────────────────────
|
| 56 |
# 1. 라이브러리 가져오기
|
| 57 |
# ─────────────────────────────────────────────
|
| 58 |
-
import os
|
| 59 |
from pathlib import Path
|
| 60 |
|
| 61 |
import streamlit as st
|
| 62 |
import google.generativeai as genai
|
| 63 |
import chromadb
|
| 64 |
|
| 65 |
-
# dotenv는 로컬 개발 시 .env 파일에서 API 키를 불러올 때만 사용
|
| 66 |
-
try:
|
| 67 |
-
from dotenv import load_dotenv
|
| 68 |
-
load_dotenv()
|
| 69 |
-
except ImportError:
|
| 70 |
-
pass
|
| 71 |
-
|
| 72 |
|
| 73 |
# ─────────────────────────────────────────────
|
| 74 |
# 2. 전역 설정값
|
|
@@ -83,31 +73,23 @@ EMBED_MODEL = "gemini-embedding-001"
|
|
| 83 |
GEN_MODEL = "gemini-2.5-flash-lite"
|
| 84 |
EMBED_DIM = 768
|
| 85 |
TOP_K = 5
|
|
|
|
| 86 |
|
| 87 |
|
| 88 |
# ─────────────────────────────────────────────
|
| 89 |
# 3. Gemini API 초기화
|
| 90 |
# ─────────────────────────────────────────────
|
| 91 |
-
def init_gemini() -> bool:
|
| 92 |
"""
|
| 93 |
-
Gemini API 키를
|
| 94 |
|
| 95 |
-
키
|
| 96 |
-
|
| 97 |
-
`os.environ`에 주입됩니다.
|
| 98 |
-
- Hugging Face Spaces 배포: Space의 Settings → Secrets에 등록한 값이
|
| 99 |
-
컨테이너 환경변수로 자동 주입됩니다.
|
| 100 |
"""
|
| 101 |
-
api_key =
|
| 102 |
|
| 103 |
if not api_key:
|
| 104 |
-
st.
|
| 105 |
-
"❌ **GEMINI_API_KEY를 찾을 수 없습니다.**\n\n"
|
| 106 |
-
"**로컬 개발 시:** 같은 폴더의 `.env` 파일에 "
|
| 107 |
-
"`GEMINI_API_KEY=본인키` 한 줄을 추가하세요.\n\n"
|
| 108 |
-
"**Hugging Face Spaces 배포 시:** Space의 Settings → Secrets에 "
|
| 109 |
-
"`GEMINI_API_KEY` 항목을 추가하세요."
|
| 110 |
-
)
|
| 111 |
return False
|
| 112 |
|
| 113 |
genai.configure(api_key=api_key)
|
|
@@ -152,9 +134,6 @@ def get_collection():
|
|
| 152 |
`chroma_election_db/` 폴더와 컬렉션이 존재하지 않으면
|
| 153 |
오류를 표시하고 앱을 중단합니다.
|
| 154 |
"""
|
| 155 |
-
if not init_gemini():
|
| 156 |
-
st.stop()
|
| 157 |
-
|
| 158 |
if not Path(DB_PATH).exists():
|
| 159 |
st.error(
|
| 160 |
f"❌ Chroma DB 폴더를 찾을 수 없습니다: `{DB_PATH}`\n\n"
|
|
@@ -311,6 +290,21 @@ def main():
|
|
| 311 |
# `with st.sidebar:` 블록 안의 모든 위젯은 좌측 사이드바에 그려진다.
|
| 312 |
# 블록을 벗어나면 다시 메인 영역으로 돌아간다(파이썬의 컨텍스트 매니저).
|
| 313 |
with st.sidebar:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
st.header("📌 사용 안내")
|
| 315 |
st.markdown("""
|
| 316 |
**이 챗봇은?**
|
|
@@ -378,6 +372,11 @@ def main():
|
|
| 378 |
|
| 379 |
# 이번 재실행에서 질문이 있을 때만 답변 생성 절차로 들어간다.
|
| 380 |
if query:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
# 사용자가 보낸 메시지를 즉시 화면에 그려 준다(반응성 ↑).
|
| 382 |
with st.chat_message("user"):
|
| 383 |
st.markdown(query)
|
|
|
|
| 29 |
처음 한 번만 아래 명령으로 필요한 패키지를 설치합니다.
|
| 30 |
(가상환경(venv) 안에서 실행하는 것을 권장합니다.)
|
| 31 |
|
| 32 |
+
pip install streamlit google-generativeai chromadb
|
| 33 |
|
| 34 |
또는 `requirements.txt` 파일에 다음을 적어두고 한 번에 설치할 수도 있습니다.
|
| 35 |
|
| 36 |
streamlit
|
| 37 |
google-generativeai
|
| 38 |
chromadb
|
|
|
|
| 39 |
|
| 40 |
→ pip install -r requirements.txt
|
| 41 |
|
| 42 |
[실행 방법]
|
| 43 |
+
1) 사전 빌드된 `chroma_election_db/` 폴더가 같은 경로에 있는지 확인합니다.
|
| 44 |
+
2) 아래 명령으로 앱을 띄웁니다(파이썬 직접 실행이 아니라 `streamlit run` 사용!).
|
|
|
|
|
|
|
| 45 |
|
| 46 |
streamlit run RAG챗봇_배포.py
|
| 47 |
|
| 48 |
+
3) 브라우저에서 본인의 Gemini API key를 입력한 뒤 질문합니다.
|
| 49 |
브라우저가 자동으로 열리지 않으면 터미널에 표시된 http://localhost:8501 로 접속하세요.
|
| 50 |
=====================================================================
|
| 51 |
"""
|
|
|
|
| 53 |
# ─────────────────────────────────────────────
|
| 54 |
# 1. 라이브러리 가져오기
|
| 55 |
# ─────────────────────────────────────────────
|
|
|
|
| 56 |
from pathlib import Path
|
| 57 |
|
| 58 |
import streamlit as st
|
| 59 |
import google.generativeai as genai
|
| 60 |
import chromadb
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
# ─────────────────────────────────────────────
|
| 64 |
# 2. 전역 설정값
|
|
|
|
| 73 |
GEN_MODEL = "gemini-2.5-flash-lite"
|
| 74 |
EMBED_DIM = 768
|
| 75 |
TOP_K = 5
|
| 76 |
+
GEMINI_API_KEY_DOC_URL = "https://ai.google.dev/gemini-api/docs/api-key"
|
| 77 |
|
| 78 |
|
| 79 |
# ─────────────────────────────────────────────
|
| 80 |
# 3. Gemini API 초기화
|
| 81 |
# ─────────────────────────────────────────────
|
| 82 |
+
def init_gemini(api_key: str) -> bool:
|
| 83 |
"""
|
| 84 |
+
사용자가 화면에 입력한 Gemini API 키로 SDK를 설정합니다.
|
| 85 |
|
| 86 |
+
Hugging Face Spaces에서는 앱 운영자가 공용 키를 Secrets에 넣지 않고,
|
| 87 |
+
각 사용자가 본인의 키를 직접 입력해 사용합니다.
|
|
|
|
|
|
|
|
|
|
| 88 |
"""
|
| 89 |
+
api_key = api_key.strip()
|
| 90 |
|
| 91 |
if not api_key:
|
| 92 |
+
st.warning("Gemini API key를 입력한 뒤 질문해 주세요.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
return False
|
| 94 |
|
| 95 |
genai.configure(api_key=api_key)
|
|
|
|
| 134 |
`chroma_election_db/` 폴더와 컬렉션이 존재하지 않으면
|
| 135 |
오류를 표시하고 앱을 중단합니다.
|
| 136 |
"""
|
|
|
|
|
|
|
|
|
|
| 137 |
if not Path(DB_PATH).exists():
|
| 138 |
st.error(
|
| 139 |
f"❌ Chroma DB 폴더를 찾을 수 없습니다: `{DB_PATH}`\n\n"
|
|
|
|
| 290 |
# `with st.sidebar:` 블록 안의 모든 위젯은 좌측 사이드바에 그려진다.
|
| 291 |
# 블록을 벗어나면 다시 메인 영역으로 돌아간다(파이썬의 컨텍스트 매니저).
|
| 292 |
with st.sidebar:
|
| 293 |
+
st.header("🔑 Gemini API key")
|
| 294 |
+
st.text_input(
|
| 295 |
+
"본인의 Gemini API key",
|
| 296 |
+
type="password",
|
| 297 |
+
key="gemini_api_key",
|
| 298 |
+
placeholder="AIza...",
|
| 299 |
+
help="입력한 key는 브라우저 세션 동안만 사용하며 앱 코드나 저장소에 저장하지 않습니다."
|
| 300 |
+
)
|
| 301 |
+
st.markdown(
|
| 302 |
+
f"API key가 없다면 [Google 공식 문서에서 발급 방법 확인]({GEMINI_API_KEY_DOC_URL})"
|
| 303 |
+
" 후 입력하세요."
|
| 304 |
+
)
|
| 305 |
+
st.caption(f"사용 모델: `{GEN_MODEL}`")
|
| 306 |
+
st.divider()
|
| 307 |
+
|
| 308 |
st.header("📌 사용 안내")
|
| 309 |
st.markdown("""
|
| 310 |
**이 챗봇은?**
|
|
|
|
| 372 |
|
| 373 |
# 이번 재실행에서 질문이 있을 때만 답변 생성 절차로 들어간다.
|
| 374 |
if query:
|
| 375 |
+
api_key = st.session_state.get("gemini_api_key", "")
|
| 376 |
+
|
| 377 |
+
if not init_gemini(api_key):
|
| 378 |
+
st.stop()
|
| 379 |
+
|
| 380 |
# 사용자가 보낸 메시지를 즉시 화면에 그려 준다(반응성 ↑).
|
| 381 |
with st.chat_message("user"):
|
| 382 |
st.markdown(query)
|