jzou19950715 commited on
Commit
7eeac78
Β·
verified Β·
1 Parent(s): 246c732

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -63
app.py CHANGED
@@ -2,25 +2,29 @@ import gradio as gr
2
  from openai import OpenAI
3
  import requests
4
  import json
5
- from typing import List, Dict, Optional
 
6
 
7
  class GifChatBot:
8
  def __init__(self):
9
  self.openai_client = None
10
  self.giphy_key = None
11
  self.chat_history = []
12
-
 
13
  def setup_keys(self, openai_key: str, giphy_key: str) -> str:
14
  """Initialize API clients with user's keys"""
15
  try:
16
  self.openai_client = OpenAI(api_key=openai_key)
17
  self.giphy_key = giphy_key
18
- # Test the keys
19
  self._test_giphy_key()
20
  self._test_openai_key()
 
21
  return "βœ… Setup successful! Let's chat!"
22
- except Exception as e:
23
- return f"❌ Error setting up: {str(e)}"
 
24
 
25
  def _test_giphy_key(self):
26
  """Test if GIPHY key is valid"""
@@ -43,49 +47,116 @@ class GifChatBot:
43
  raise Exception("Invalid OpenAI API key")
44
 
45
  def get_gif(self, search_query: str) -> Optional[str]:
46
- """Search GIPHY for a relevant GIF"""
47
  try:
 
 
 
 
 
 
 
 
 
48
  response = requests.get(
49
  "https://api.giphy.com/v1/gifs/search",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  params={
51
- "api_key": self.giphy_key,
52
- "q": search_query,
53
- "limit": 10,
54
- "rating": "pg-13"
55
  }
56
  )
 
57
  if response.status_code == 200:
58
  data = response.json()
59
  if data["data"]:
60
- import random
61
- gif = random.choice(data["data"])
62
- return gif["images"]["original"]["url"]
63
- except Exception as e:
64
- print(f"GIPHY error: {e}")
65
  return None
66
 
67
- def chat(self, message: str, history: List[List[str]]) -> tuple[str, List[List[str]]]:
68
- """Main chat function with GIF support"""
69
- if not self.openai_client or not self.giphy_key:
70
- return "Please set up your API keys first!", history
 
 
 
 
 
 
 
 
71
 
72
  try:
73
- # Create the system message that encourages proactive GIF usage
74
- system_message = """You are a fun, internet-savvy friend who loves expressing yourself through GIFs!
75
- You can and should proactively use GIFs when appropriate to make the conversation more engaging.
 
 
 
 
 
 
 
76
 
77
- To use a GIF, simply include [GIF: description] in your message where you want the GIF to appear.
78
- For example: "That's amazing! [GIF: mind blown explosion] I can't believe it!"
 
 
79
 
80
- Keep your responses conversational and natural, and use GIFs to enhance emotional expression or reactions.
81
- Don't overuse GIFs - use them naturally like a real person would in chat."""
82
 
83
  # Prepare conversation history
84
  messages = [{"role": "system", "content": system_message}]
85
- for h in history:
86
  messages.extend([
87
- {"role": "user", "content": h[0]},
88
- {"role": "assistant", "content": h[1]}
89
  ])
90
  messages.append({"role": "user", "content": message})
91
 
@@ -115,48 +186,61 @@ class GifChatBot:
115
  final_response += part[gif_desc_end + 1:]
116
 
117
  history.append([message, final_response])
118
- return final_response, history
119
 
120
- except Exception as e:
121
- return f"Oops! Something went wrong: {str(e)}", history
 
122
 
123
- # Create Gradio interface
124
  def create_interface():
 
125
  bot = GifChatBot()
126
 
127
- with gr.Blocks() as interface:
128
  gr.Markdown("""
129
- # Fun AI Friend with GIFs! πŸŽ‰
130
- First, enter your API keys below to get started. Then chat away!
 
131
  """)
132
 
133
  with gr.Row():
134
- openai_key = gr.Textbox(
135
- label="OpenAI API Key",
136
- placeholder="sk-...",
137
- type="password"
138
- )
139
- giphy_key = gr.Textbox(
140
- label="GIPHY API Key",
141
- placeholder="Enter your GIPHY API key",
142
- type="password"
143
- )
 
 
 
 
144
 
145
- setup_button = gr.Button("Set up Keys")
146
  setup_status = gr.Textbox(label="Setup Status")
147
 
148
  chatbot = gr.Chatbot(
149
  label="Chat",
150
  bubble_full_width=False,
151
  show_label=False,
152
- height=400
153
- )
154
- msg = gr.Textbox(
155
- label="Type your message",
156
- placeholder="Say something...",
157
- show_label=False
158
  )
159
- clear = gr.Button("Clear Chat")
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
  # Set up event handlers
162
  setup_button.click(
@@ -165,24 +249,27 @@ def create_interface():
165
  outputs=setup_status
166
  )
167
 
168
- msg.submit(
169
  bot.chat,
170
- inputs=[msg, chatbot],
171
- outputs=[msg, chatbot]
172
  )
173
 
174
- clear.click(lambda: None, None, chatbot)
 
 
 
175
 
176
  gr.Markdown("""
177
- ### Notes:
178
- - The AI will naturally use GIFs when appropriate in conversation
179
- - Your API keys are never stored and are only used for this session
180
- - Have fun chatting! 🎈
 
181
  """)
182
 
183
  return interface
184
 
185
- # Launch the app
186
  if __name__ == "__main__":
187
  demo = create_interface()
188
  demo.launch()
 
2
  from openai import OpenAI
3
  import requests
4
  import json
5
+ from typing import List, Dict, Optional, Tuple
6
+ import random
7
 
8
  class GifChatBot:
9
  def __init__(self):
10
  self.openai_client = None
11
  self.giphy_key = None
12
  self.chat_history = []
13
+ self.is_initialized = False
14
+
15
  def setup_keys(self, openai_key: str, giphy_key: str) -> str:
16
  """Initialize API clients with user's keys"""
17
  try:
18
  self.openai_client = OpenAI(api_key=openai_key)
19
  self.giphy_key = giphy_key
20
+ # Test both keys
21
  self._test_giphy_key()
22
  self._test_openai_key()
23
+ self.is_initialized = True
24
  return "βœ… Setup successful! Let's chat!"
25
+ except Exception as error:
26
+ self.is_initialized = False
27
+ return f"❌ Error setting up: {str(error)}"
28
 
29
  def _test_giphy_key(self):
30
  """Test if GIPHY key is valid"""
 
47
  raise Exception("Invalid OpenAI API key")
48
 
49
  def get_gif(self, search_query: str) -> Optional[str]:
50
+ """Search GIPHY with natural, contextual queries"""
51
  try:
52
+ # Keep the search query simple and contextual
53
+ params = {
54
+ 'api_key': self.giphy_key,
55
+ 'q': search_query,
56
+ 'limit': 15,
57
+ 'rating': 'pg-13',
58
+ 'bundle': 'messaging_non_clips'
59
+ }
60
+
61
  response = requests.get(
62
  "https://api.giphy.com/v1/gifs/search",
63
+ params=params
64
+ )
65
+
66
+ if response.status_code == 200:
67
+ data = response.json()
68
+ if data["data"]:
69
+ # Filter for good quality GIFs
70
+ good_gifs = [
71
+ gif for gif in data["data"]
72
+ if self._is_good_quality_gif(gif)
73
+ ]
74
+
75
+ if good_gifs:
76
+ return random.choice(good_gifs)["images"]["original"]["url"]
77
+
78
+ # Fallback to trending if no good matches
79
+ return self._get_trending_gif()
80
+
81
+ except Exception as error:
82
+ print(f"GIPHY error: {error}")
83
+ return None
84
+
85
+ def _is_good_quality_gif(self, gif: Dict) -> bool:
86
+ """Check if a GIF meets quality criteria"""
87
+ try:
88
+ # Avoid very long GIFs
89
+ if int(gif.get("images", {}).get("original", {}).get("frames", 50)) > 50:
90
+ return False
91
+
92
+ # Check if size is reasonable (under 2MB)
93
+ if int(gif.get("images", {}).get("original", {}).get("size", 0)) > 2000000:
94
+ return False
95
+
96
+ return True
97
+ except:
98
+ return True
99
+
100
+ def _get_trending_gif(self) -> Optional[str]:
101
+ """Get a trending GIF as fallback"""
102
+ try:
103
+ response = requests.get(
104
+ "https://api.giphy.com/v1/gifs/trending",
105
  params={
106
+ 'api_key': self.giphy_key,
107
+ 'limit': 25,
108
+ 'rating': 'pg-13',
109
+ 'bundle': 'messaging_non_clips'
110
  }
111
  )
112
+
113
  if response.status_code == 200:
114
  data = response.json()
115
  if data["data"]:
116
+ return random.choice(data["data"])["images"]["original"]["url"]
117
+ except Exception as error:
118
+ print(f"Error getting trending GIF: {error}")
 
 
119
  return None
120
 
121
+ def reset_chat(self) -> Tuple[str, List[List[str]]]:
122
+ """Reset the chat history"""
123
+ self.chat_history = []
124
+ return "", []
125
+
126
+ def chat(self, message: str, history: List[List[str]]) -> Tuple[str, List[List[str]], str]:
127
+ """Main chat function with natural GIF integration"""
128
+ if not self.is_initialized:
129
+ return message, history, "Please set up your API keys first!"
130
+
131
+ if not message.strip():
132
+ return message, history, ""
133
 
134
  try:
135
+ # System message emphasizing natural GIF search
136
+ system_message = """You are a supportive, empathetic friend who uses GIFs naturally in conversation.
137
+ When using GIFs, keep search terms simple and contextual, like humans do:
138
+
139
+ Examples of natural GIF searches:
140
+ - When someone's hungry: [GIF: hungry]
141
+ - When comforting someone: [GIF: comforting hug]
142
+ - When celebrating: [GIF: celebration]
143
+ - When confused: [GIF: confused]
144
+ - When agreeing strongly: [GIF: absolutely yes]
145
 
146
+ Keep your responses:
147
+ 1. Empathetic and supportive
148
+ 2. Context-aware (reference previous messages naturally)
149
+ 3. Use GIFs that match the emotional context
150
 
151
+ Use 0-1 GIFs per message unless the context really calls for more.
152
+ The GIF should enhance your message, not replace it."""
153
 
154
  # Prepare conversation history
155
  messages = [{"role": "system", "content": system_message}]
156
+ for chat in history:
157
  messages.extend([
158
+ {"role": "user", "content": chat[0]},
159
+ {"role": "assistant", "content": chat[1]}
160
  ])
161
  messages.append({"role": "user", "content": message})
162
 
 
186
  final_response += part[gif_desc_end + 1:]
187
 
188
  history.append([message, final_response])
189
+ return "", history, ""
190
 
191
+ except Exception as error:
192
+ error_message = f"Oops! Something went wrong: {str(error)}"
193
+ return message, history, error_message
194
 
 
195
  def create_interface():
196
+ """Create the Gradio interface"""
197
  bot = GifChatBot()
198
 
199
+ with gr.Blocks(theme=gr.themes.Soft()) as interface:
200
  gr.Markdown("""
201
+ # 🎭 Friendly Chat Bot with GIFs
202
+ Chat with an empathetic AI friend who expresses themselves through GIFs!
203
+ Enter your API keys below to start.
204
  """)
205
 
206
  with gr.Row():
207
+ with gr.Column(scale=1):
208
+ openai_key = gr.Textbox(
209
+ label="OpenAI API Key",
210
+ placeholder="sk-...",
211
+ type="password",
212
+ scale=2
213
+ )
214
+ with gr.Column(scale=1):
215
+ giphy_key = gr.Textbox(
216
+ label="GIPHY API Key",
217
+ placeholder="Enter your GIPHY API key",
218
+ type="password",
219
+ scale=2
220
+ )
221
 
222
+ setup_button = gr.Button("Set up Keys", variant="primary")
223
  setup_status = gr.Textbox(label="Setup Status")
224
 
225
  chatbot = gr.Chatbot(
226
  label="Chat",
227
  bubble_full_width=False,
228
  show_label=False,
229
+ height=450
 
 
 
 
 
230
  )
231
+
232
+ with gr.Row():
233
+ with gr.Column(scale=4):
234
+ message_box = gr.Textbox(
235
+ label="Type your message",
236
+ placeholder="Say something...",
237
+ show_label=False,
238
+ container=False
239
+ )
240
+ with gr.Column(scale=1):
241
+ clear_button = gr.Button("Clear Chat", variant="secondary")
242
+
243
+ error_box = gr.Textbox(label="Error Messages", visible=True)
244
 
245
  # Set up event handlers
246
  setup_button.click(
 
249
  outputs=setup_status
250
  )
251
 
252
+ message_box.submit(
253
  bot.chat,
254
+ inputs=[message_box, chatbot],
255
+ outputs=[message_box, chatbot, error_box]
256
  )
257
 
258
+ clear_button.click(
259
+ bot.reset_chat,
260
+ outputs=[message_box, chatbot]
261
+ )
262
 
263
  gr.Markdown("""
264
+ ### Tips:
265
+ - 🀝 Share how you're feeling - the AI will respond empathetically
266
+ - πŸ’­ The conversation is context-aware
267
+ - 🎯 GIFs are chosen to match the emotional context
268
+ - πŸ”„ Use 'Clear Chat' to start fresh
269
  """)
270
 
271
  return interface
272
 
 
273
  if __name__ == "__main__":
274
  demo = create_interface()
275
  demo.launch()