JUNGU commited on
Commit
732091b
Β·
verified Β·
1 Parent(s): 7af9de2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -224
app.py CHANGED
@@ -1,232 +1,48 @@
1
- # ν•„μš”ν•œ 라이브러리λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.
2
  import gradio as gr
3
  import google.generativeai as genai
4
  import os
5
- import logging
6
 
7
- # λ‘œκΉ… μ„€μ •
8
- logging.basicConfig(level=logging.INFO)
9
- logger = logging.getLogger(__name__)
 
10
 
11
- # μ‹œμž‘ μ‹œ ν™˜κ²½λ³€μˆ˜ 확인
12
- GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
13
- if GEMINI_API_KEY:
14
- logger.info("API ν‚€κ°€ ν™˜κ²½λ³€μˆ˜μ—μ„œ κ°μ§€λ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
15
- logger.info(f"API ν‚€ 미리보기: {GEMINI_API_KEY[:8]}...")
16
- else:
17
- logger.warning("GEMINI_API_KEYκ°€ ν™˜κ²½λ³€μˆ˜μ—μ„œ κ°μ§€λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.")
18
-
19
- # --- UI 및 챗봇 μ„€λͺ… ---
20
- # Gradio Blocksλ₯Ό μ‚¬μš©ν•˜μ—¬ μ’€ 더 μœ μ—°ν•œ UIλ₯Ό κ΅¬μ„±ν•©λ‹ˆλ‹€.
21
- with gr.Blocks(theme=gr.themes.Default(primary_hue="blue")) as demo:
22
- gr.Markdown(
23
- """
24
- # β™ŠοΈ Gemini API 챗봇
25
- Google Gemini APIλ₯Ό μ‚¬μš©ν•˜λŠ” μ±—λ΄‡μž…λ‹ˆλ‹€.
26
-
27
- **μ€‘μš”**: Hugging Face Spaces의 **Settings β†’ Repository secrets**에 `GEMINI_API_KEY`κ°€ μ„€μ •λ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
28
-
29
- [API ν‚€ λ°œκΈ‰λ°›κΈ°](https://aistudio.google.com/app/apikey)
30
- """
31
- )
32
-
33
- # ν™˜κ²½λ³€μˆ˜ μƒνƒœ ν‘œμ‹œ
34
- with gr.Row():
35
- env_status = gr.Textbox(
36
- label="ν™˜κ²½λ³€μˆ˜ μƒνƒœ",
37
- value=f"GEMINI_API_KEY: {'βœ… 섀정됨' if GEMINI_API_KEY else '❌ μ„€μ •λ˜μ§€ μ•ŠμŒ'}",
38
- interactive=False
39
- )
40
-
41
- # Gradio 챗봇 UI μ»΄ν¬λ„ŒνŠΈ - type νŒŒλΌλ―Έν„° μΆ”κ°€
42
- chatbot = gr.Chatbot(
43
- label="Gemini 챗봇",
44
- height=600,
45
- type="messages" # 이 νŒŒλΌλ―Έν„°λ₯Ό μΆ”κ°€ν•˜μ—¬ κ²½κ³  ν•΄κ²°
46
- )
47
-
48
- with gr.Row():
49
- # μ‚¬μš©μž λ©”μ‹œμ§€ μž…λ ₯λž€
50
- msg = gr.Textbox(
51
- label="λ©”μ‹œμ§€ μž…λ ₯",
52
- placeholder="무엇이든 λ¬Όμ–΄λ³΄μ„Έμš”...",
53
- scale=7,
54
- lines=1
55
- )
56
- # 전솑 λ²„νŠΌ
57
- submit_button = gr.Button("전솑", variant="primary", scale=1)
58
-
59
- with gr.Accordion("κ³ κΈ‰ μ„€μ •", open=False):
60
- # LLM의 역할을 μ •μ˜ν•˜λŠ” μ‹œμŠ€ν…œ λ©”μ‹œμ§€
61
- system_message = gr.Textbox(
62
- value="You are a helpful and friendly chatbot.",
63
- label="μ‹œμŠ€ν…œ λ©”μ‹œμ§€",
64
- lines=2
65
- )
66
- # λͺ¨λΈμ˜ μ°½μ˜μ„±μ„ μ‘°μ ˆν•˜λŠ” μŠ¬λΌμ΄λ”
67
- temperature = gr.Slider(
68
- minimum=0.0,
69
- maximum=1.0,
70
- value=0.7,
71
- step=0.1,
72
- label="Temperature"
73
- )
74
- # 생성할 μ΅œλŒ€ 토큰 수λ₯Ό μ‘°μ ˆν•˜λŠ” μŠ¬λΌμ΄λ”
75
- max_tokens = gr.Slider(
76
- minimum=1,
77
- maximum=4096,
78
- value=1024,
79
- step=1,
80
- label="Max new tokens"
81
- )
82
-
83
- # ν™˜κ²½λ³€μˆ˜ μƒˆλ‘œκ³ μΉ¨ λ²„νŠΌ
84
- refresh_button = gr.Button("πŸ”„ ν™˜κ²½λ³€μˆ˜ μƒˆλ‘œκ³ μΉ¨", size="sm")
85
-
86
- def refresh_env_status():
87
- """ν™˜κ²½λ³€μˆ˜ μƒνƒœλ₯Ό μƒˆλ‘œκ³ μΉ¨ν•©λ‹ˆλ‹€."""
88
- global GEMINI_API_KEY
89
- GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
90
- status = f"GEMINI_API_KEY: {'βœ… 섀정됨' if GEMINI_API_KEY else '❌ μ„€μ •λ˜μ§€ μ•ŠμŒ'}"
91
- if GEMINI_API_KEY:
92
- status += f" (미리보기: {GEMINI_API_KEY[:8]}...)"
93
- return status
94
-
95
- refresh_button.click(refresh_env_status, outputs=[env_status])
96
-
97
- # --- Gemini API 호좜 ν•¨μˆ˜ ---
98
- def respond(message, chat_history, system_prompt, temp, max_output_tokens):
99
- # ν•¨μˆ˜κ°€ 호좜될 λ•Œλ§ˆλ‹€ ν™˜κ²½λ³€μˆ˜μ—μ„œ API ν‚€λ₯Ό λ‹€μ‹œ 확인
100
- api_key = os.environ.get("GEMINI_API_KEY")
101
-
102
- # 디버깅을 μœ„ν•œ μΆ”κ°€ 정보
103
- logger.info(f"API ν‚€ 확인: {'있음' if api_key else 'μ—†μŒ'}")
104
-
105
- # ν™˜κ²½λ³€μˆ˜μ—μ„œ κ°€μ Έμ˜¨ API ν‚€κ°€ μ—†μœΌλ©΄ μ•ˆλ‚΄ λ©”μ‹œμ§€λ₯Ό λ„μ›λ‹ˆλ‹€.
106
- if not api_key:
107
- error_msg = """⚠️ **였λ₯˜**: `GEMINI_API_KEY`κ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
108
-
109
- **ν•΄κ²° 방법**:
110
- 1. Hugging Face Spaces의 **Settings** νƒ­μœΌλ‘œ 이동
111
- 2. **Repository secrets** μ„Ήμ…˜ μ°ΎκΈ°
112
- 3. **New secret** λ²„νŠΌ 클릭
113
- 4. Name: `GEMINI_API_KEY`, Value: μ‹€μ œ API ν‚€ μž…λ ₯
114
- 5. **Save** 클릭
115
- 6. Spaceλ₯Ό **μž¬μ‹œμž‘** (Settings β†’ Factory reboot)
116
-
117
- **μ°Έκ³ **: Private spaceκ°€ μ•„λ‹Œ κ²½μš°μ—λ„ secretsλŠ” μ•ˆμ „ν•˜κ²Œ λ³΄ν˜Έλ©λ‹ˆλ‹€."""
118
- yield error_msg
119
- return
120
-
121
- try:
122
- # API ν‚€λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.
123
- genai.configure(api_key=api_key)
124
- logger.info("API ν‚€ μ„€μ • 성곡")
125
- except Exception as e:
126
- yield f"API ν‚€ 섀정에 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {str(e)}"
127
- return
128
-
129
- # μ‚¬μš©ν•  λͺ¨λΈκ³Ό μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈλ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.
130
- try:
131
- # μ‚¬μš© κ°€λŠ₯ν•œ λͺ¨λΈλ‘œ λ³€κ²½
132
- model = genai.GenerativeModel(
133
- model_name='gemini-2.0-flash', # μ•ˆμ •μ μΈ λͺ¨λΈ μ‚¬μš©
134
- system_instruction=system_prompt
135
- )
136
- except Exception as e:
137
- yield f"λͺ¨λΈ μ΄ˆκΈ°ν™” 였λ₯˜: {str(e)}\nμ‚¬μš© κ°€λŠ₯ν•œ λͺ¨λΈ: gemini-1.5-flash, gemini-1.5-pro"
138
- return
139
-
140
- # Gradio의 λŒ€ν™” 기둝을 Gemini APIκ°€ 이해할 수 μžˆλŠ” ν˜•μ‹μœΌλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.
141
- gemini_history = []
142
-
143
- # type="messages" ν˜•μ‹μ— 맞게 처리
144
- if isinstance(chat_history, list) and len(chat_history) > 0:
145
- # μƒˆλ‘œμš΄ λ©”μ‹œμ§€ ν˜•μ‹ 처리
146
- if isinstance(chat_history[0], dict):
147
- for msg in chat_history:
148
- if msg.get("role") == "user":
149
- gemini_history.append({"role": "user", "parts": [msg.get("content", "")]})
150
- elif msg.get("role") == "assistant":
151
- gemini_history.append({"role": "model", "parts": [msg.get("content", "")]})
152
- # 이전 νŠœν”Œ ν˜•μ‹λ„ 지원
153
- else:
154
- for user_msg, model_msg in chat_history:
155
- if user_msg:
156
- gemini_history.append({"role": "user", "parts": [user_msg]})
157
- if model_msg:
158
- gemini_history.append({"role": "model", "parts": [model_msg]})
159
-
160
- # 이전 λŒ€ν™” 기둝을 λ°”νƒ•μœΌλ‘œ μ±„νŒ… μ„Έμ…˜μ„ μ‹œμž‘ν•©λ‹ˆλ‹€.
161
- chat = model.start_chat(history=gemini_history)
162
-
163
- # λͺ¨λΈ 생성 κ΄€λ ¨ 섀정을 κ΅¬μ„±ν•©λ‹ˆλ‹€.
164
- generation_config = genai.types.GenerationConfig(
165
- temperature=temp,
166
- max_output_tokens=int(max_output_tokens),
167
- )
168
-
169
- try:
170
- # 슀트리밍 λ°©μ‹μœΌλ‘œ λ©”μ‹œμ§€λ₯Ό 보내고 응닡을 λ°›μŠ΅λ‹ˆλ‹€.
171
- response = chat.send_message(
172
- message,
173
- stream=True,
174
- generation_config=generation_config
175
- )
176
-
177
- # 슀트리밍 응닡을 μ‹€μ‹œκ°„μœΌλ‘œ UI에 ν‘œμ‹œν•©λ‹ˆλ‹€.
178
- full_response = ""
179
- for chunk in response:
180
- if hasattr(chunk, 'text'):
181
- full_response += chunk.text
182
- yield full_response
183
-
184
- except Exception as e:
185
- # API 호좜 쀑 μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ UI에 ν‘œμ‹œν•©λ‹ˆλ‹€.
186
- error_detail = str(e)
187
- if "API_KEY_INVALID" in error_detail:
188
- yield "❌ API ν‚€κ°€ μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ˜¬λ°”λ₯Έ API 킀인지 ν™•μΈν•΄μ£Όμ„Έμš”."
189
- elif "QUOTA_EXCEEDED" in error_detail:
190
- yield "❌ API μ‚¬μš©λŸ‰ ν•œλ„λ₯Ό μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."
191
- else:
192
- yield f"응닡 생성 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {error_detail}"
193
-
194
- # --- Gradio 이벀트 λ¦¬μŠ€λ„ˆ ---
195
- def on_submit(message, chat_history, system_prompt, temp, max_output_tokens):
196
- if not message.strip():
197
- return "", chat_history
198
-
199
- # μƒˆλ‘œμš΄ λ©”μ‹œμ§€ ν˜•μ‹ μ‚¬μš©
200
- chat_history = chat_history or []
201
-
202
- # μ‚¬μš©μž λ©”μ‹œμ§€ μΆ”κ°€
203
- chat_history.append({"role": "user", "content": message})
204
-
205
- # 봇 응닡 슀트리밍
206
- bot_response_stream = respond(message, chat_history[:-1], system_prompt, temp, max_output_tokens)
207
-
208
- for partial_response in bot_response_stream:
209
- # λ§ˆμ§€λ§‰ λ©”μ‹œμ§€κ°€ μ‚¬μš©μž λ©”μ‹œμ§€μΈ κ²½μš°μ—λ§Œ 봇 응닡 μΆ”κ°€
210
- if chat_history and chat_history[-1]["role"] == "user":
211
- chat_history.append({"role": "assistant", "content": partial_response})
212
- else:
213
- # 봇 응닡 μ—…λ°μ΄νŠΈ
214
- chat_history[-1]["content"] = partial_response
215
- yield "", chat_history
216
 
217
- # 이벀트 ν•Έλ“€λŸ¬ μ—°κ²°
218
- msg.submit(
219
- on_submit,
220
- [msg, chatbot, system_message, temperature, max_tokens],
221
- [msg, chatbot]
222
- )
223
- submit_button.click(
224
- on_submit,
225
- [msg, chatbot, system_message, temperature, max_tokens],
226
- [msg, chatbot]
227
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
 
229
- # 메인 μ‹€ν–‰ λΆ€λΆ„
230
  if __name__ == "__main__":
231
- # 디버깅 λͺ¨λ“œλ‘œ μ‹€ν–‰
232
- demo.launch(debug=True)
 
 
1
  import gradio as gr
2
  import google.generativeai as genai
3
  import os
 
4
 
5
+ # API ν‚€ μ„€μ •
6
+ api_key = os.environ.get("GEMINI_API_KEY")
7
+ if api_key:
8
+ genai.configure(api_key=api_key)
9
 
10
+ def chat(message, history):
11
+ if not api_key:
12
+ return "❌ API ν‚€κ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. HF Spaces Settingsμ—μ„œ GEMINI_API_KEYλ₯Ό μΆ”κ°€ν•˜μ„Έμš”."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ try:
15
+ # Gemini λͺ¨λΈ μ΄ˆκΈ°ν™”
16
+ model = genai.GenerativeModel('gemini-2.0-flash')
17
+
18
+ # λŒ€ν™” 기둝 λ³€ν™˜
19
+ chat_history = []
20
+ for human, assistant in history:
21
+ if human:
22
+ chat_history.append({"role": "user", "parts": [human]})
23
+ if assistant:
24
+ chat_history.append({"role": "model", "parts": [assistant]})
25
+
26
+ # μ±„νŒ… μ„Έμ…˜ μ‹œμž‘
27
+ chat_session = model.start_chat(history=chat_history)
28
+
29
+ # 응닡 생성
30
+ response = chat_session.send_message(message)
31
+ return response.text
32
+
33
+ except Exception as e:
34
+ return f"❌ 였λ₯˜ λ°œμƒ: {str(e)}"
35
+
36
+ # Gradio μΈν„°νŽ˜μ΄μŠ€
37
+ demo = gr.ChatInterface(
38
+ fn=chat,
39
+ title="πŸ€– Gemini 챗봇",
40
+ description="Google Gemini APIλ₯Ό μ‚¬μš©ν•œ κ°„λ‹¨ν•œ μ±—λ΄‡μž…λ‹ˆλ‹€.",
41
+ examples=["μ•ˆλ…•ν•˜μ„Έμš”!", "였늘 λ‚ μ”¨λŠ” μ–΄λ•Œ?", "νŒŒμ΄μ¬μ— λŒ€ν•΄ μ„€λͺ…ν•΄μ€˜"],
42
+ retry_btn=None,
43
+ undo_btn="이전 λŒ€ν™” μ‚­μ œ",
44
+ clear_btn="전체 λŒ€ν™” μ‚­μ œ",
45
+ )
46
 
 
47
  if __name__ == "__main__":
48
+ demo.launch()