jzou19950715 commited on
Commit
5f6b9ea
·
verified ·
1 Parent(s): 5c1bc2d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -44
app.py CHANGED
@@ -4,7 +4,6 @@ import requests
4
  import json
5
  from typing import List, Dict, Optional, Tuple
6
  import random
7
- import time
8
 
9
  class GifChatBot:
10
  def __init__(self):
@@ -12,14 +11,13 @@ class GifChatBot:
12
  self.giphy_key = None
13
  self.chat_history = []
14
  self.is_initialized = False
15
- self.session = requests.Session() # Use session for better performance
16
 
17
  def setup_keys(self, openai_key: str, giphy_key: str) -> str:
18
  """Initialize API clients with user's keys"""
19
  try:
20
  self.openai_client = OpenAI(api_key=openai_key)
21
  self.giphy_key = giphy_key
22
- # Test both keys
23
  self._test_giphy_key()
24
  self._test_openai_key()
25
  self.is_initialized = True
@@ -51,10 +49,7 @@ class GifChatBot:
51
  def verify_gif_url(self, gif_url: str) -> bool:
52
  """Verify if a GIF URL is accessible"""
53
  try:
54
- # Head request is faster than full GET
55
  response = self.session.head(gif_url, timeout=3)
56
-
57
- # Check if status is OK and content type is correct
58
  if response.status_code == 200:
59
  content_type = response.headers.get('content-type', '').lower()
60
  return 'gif' in content_type or 'image' in content_type
@@ -68,7 +63,7 @@ class GifChatBot:
68
  params = {
69
  'api_key': self.giphy_key,
70
  'q': search_query,
71
- 'limit': 25, # Get more options
72
  'rating': 'pg-13',
73
  'bundle': 'messaging_non_clips'
74
  }
@@ -82,11 +77,9 @@ class GifChatBot:
82
  if response.status_code == 200:
83
  data = response.json()
84
  if data["data"]:
85
- # Shuffle results for variety
86
  gifs = list(data["data"])
87
  random.shuffle(gifs)
88
 
89
- # Try GIFs until we find a good one
90
  for gif in gifs:
91
  if not self._is_good_quality_gif(gif):
92
  continue
@@ -95,9 +88,7 @@ class GifChatBot:
95
  if self.verify_gif_url(gif_url):
96
  return gif_url
97
 
98
- # If no GIFs passed validation, try trending
99
  return self._get_trending_gif()
100
-
101
  return None
102
 
103
  except Exception as error:
@@ -121,7 +112,6 @@ class GifChatBot:
121
  if response.status_code == 200:
122
  data = response.json()
123
  if data["data"]:
124
- # Try each trending GIF until we find a working one
125
  gifs = list(data["data"])
126
  random.shuffle(gifs)
127
 
@@ -137,15 +127,12 @@ class GifChatBot:
137
  def _is_good_quality_gif(self, gif: Dict) -> bool:
138
  """Check if a GIF meets quality criteria"""
139
  try:
140
- # Skip GIFs that are too long
141
  if int(gif.get("images", {}).get("original", {}).get("frames", 50)) > 50:
142
  return False
143
 
144
- # Skip GIFs that are too large
145
- if int(gif.get("images", {}).get("original", {}).get("size", 0)) > 2000000: # 2MB
146
  return False
147
 
148
- # Skip if no image data
149
  if not gif.get("images", {}).get("original", {}).get("url"):
150
  return False
151
 
@@ -153,12 +140,16 @@ class GifChatBot:
153
  except:
154
  return False
155
 
156
- def reset_chat(self) -> Tuple[str, List[List[str]]]:
157
  """Reset the chat history"""
158
  self.chat_history = []
159
- return "", []
 
 
 
 
160
 
161
- def chat(self, message: str, history: List[List[str]]) -> Tuple[str, List[List[str]], str]:
162
  """Main chat function with natural GIF integration"""
163
  if not self.is_initialized:
164
  return message, history, "Please set up your API keys first!"
@@ -167,7 +158,6 @@ class GifChatBot:
167
  return message, history, ""
168
 
169
  try:
170
- # System message emphasizing natural GIF usage
171
  system_message = """You are a supportive, empathetic friend who uses GIFs naturally in conversation.
172
  When using GIFs, keep search terms simple and contextual:
173
 
@@ -184,16 +174,11 @@ class GifChatBot:
184
 
185
  Use 0-1 GIFs per message unless the moment really calls for more."""
186
 
187
- # Prepare conversation history
188
  messages = [{"role": "system", "content": system_message}]
189
  for chat in history:
190
- messages.extend([
191
- {"role": "user", "content": chat[0]},
192
- {"role": "assistant", "content": chat[1]}
193
- ])
194
  messages.append({"role": "user", "content": message})
195
 
196
- # Get AI response
197
  response = self.openai_client.chat.completions.create(
198
  model="gpt-4o-mini",
199
  messages=messages,
@@ -201,11 +186,9 @@ class GifChatBot:
201
  max_tokens=150
202
  )
203
 
204
- # Process response and insert GIFs
205
  ai_message = response.choices[0].message.content
206
  final_response = ""
207
 
208
- # Split by GIF markers and process
209
  parts = ai_message.split("[GIF:")
210
  final_response += parts[0]
211
 
@@ -218,17 +201,14 @@ class GifChatBot:
218
  final_response += f"\n![GIF]({gif_url})\n"
219
  final_response += part[gif_desc_end + 1:]
220
 
221
- history.append([message, final_response])
 
222
  return "", history, ""
223
 
224
  except Exception as error:
225
  error_message = f"Oops! Something went wrong: {str(error)}"
226
  return message, history, error_message
227
 
228
- def cleanup(self):
229
- """Cleanup resources"""
230
- self.session.close()
231
-
232
  def create_interface():
233
  """Create the Gradio interface"""
234
  bot = GifChatBot()
@@ -262,8 +242,8 @@ def create_interface():
262
  chatbot = gr.Chatbot(
263
  label="Chat",
264
  bubble_full_width=False,
265
- show_label=False,
266
- height=450
267
  )
268
 
269
  with gr.Row():
@@ -294,7 +274,7 @@ def create_interface():
294
 
295
  clear_button.click(
296
  bot.reset_chat,
297
- outputs=[message_box, chatbot]
298
  )
299
 
300
  gr.Markdown("""
@@ -304,16 +284,9 @@ def create_interface():
304
  - 🎯 GIFs are chosen to match the emotion
305
  - 🔄 Use 'Clear Chat' to start fresh
306
  """)
307
-
308
- # Cleanup on page unload
309
- interface.load(lambda: None, [], [], _js="""() => {
310
- window.addEventListener('unload', function() {
311
- // Cleanup resources
312
- })
313
- }""")
314
 
315
  return interface
316
 
317
  if __name__ == "__main__":
318
  demo = create_interface()
319
- demo.launch()
 
4
  import json
5
  from typing import List, Dict, Optional, Tuple
6
  import random
 
7
 
8
  class GifChatBot:
9
  def __init__(self):
 
11
  self.giphy_key = None
12
  self.chat_history = []
13
  self.is_initialized = False
14
+ self.session = requests.Session()
15
 
16
  def setup_keys(self, openai_key: str, giphy_key: str) -> str:
17
  """Initialize API clients with user's keys"""
18
  try:
19
  self.openai_client = OpenAI(api_key=openai_key)
20
  self.giphy_key = giphy_key
 
21
  self._test_giphy_key()
22
  self._test_openai_key()
23
  self.is_initialized = True
 
49
  def verify_gif_url(self, gif_url: str) -> bool:
50
  """Verify if a GIF URL is accessible"""
51
  try:
 
52
  response = self.session.head(gif_url, timeout=3)
 
 
53
  if response.status_code == 200:
54
  content_type = response.headers.get('content-type', '').lower()
55
  return 'gif' in content_type or 'image' in content_type
 
63
  params = {
64
  'api_key': self.giphy_key,
65
  'q': search_query,
66
+ 'limit': 25,
67
  'rating': 'pg-13',
68
  'bundle': 'messaging_non_clips'
69
  }
 
77
  if response.status_code == 200:
78
  data = response.json()
79
  if data["data"]:
 
80
  gifs = list(data["data"])
81
  random.shuffle(gifs)
82
 
 
83
  for gif in gifs:
84
  if not self._is_good_quality_gif(gif):
85
  continue
 
88
  if self.verify_gif_url(gif_url):
89
  return gif_url
90
 
 
91
  return self._get_trending_gif()
 
92
  return None
93
 
94
  except Exception as error:
 
112
  if response.status_code == 200:
113
  data = response.json()
114
  if data["data"]:
 
115
  gifs = list(data["data"])
116
  random.shuffle(gifs)
117
 
 
127
  def _is_good_quality_gif(self, gif: Dict) -> bool:
128
  """Check if a GIF meets quality criteria"""
129
  try:
 
130
  if int(gif.get("images", {}).get("original", {}).get("frames", 50)) > 50:
131
  return False
132
 
133
+ if int(gif.get("images", {}).get("original", {}).get("size", 0)) > 2000000:
 
134
  return False
135
 
 
136
  if not gif.get("images", {}).get("original", {}).get("url"):
137
  return False
138
 
 
140
  except:
141
  return False
142
 
143
+ def reset_chat(self) -> Tuple[List[Dict[str, str]], str]:
144
  """Reset the chat history"""
145
  self.chat_history = []
146
+ return [], ""
147
+
148
+ def format_message(self, role: str, content: str) -> Dict[str, str]:
149
+ """Format message in the new Gradio chat format"""
150
+ return {"role": role, "content": content}
151
 
152
+ def chat(self, message: str, history: List[Dict[str, str]]) -> Tuple[str, List[Dict[str, str]], str]:
153
  """Main chat function with natural GIF integration"""
154
  if not self.is_initialized:
155
  return message, history, "Please set up your API keys first!"
 
158
  return message, history, ""
159
 
160
  try:
 
161
  system_message = """You are a supportive, empathetic friend who uses GIFs naturally in conversation.
162
  When using GIFs, keep search terms simple and contextual:
163
 
 
174
 
175
  Use 0-1 GIFs per message unless the moment really calls for more."""
176
 
 
177
  messages = [{"role": "system", "content": system_message}]
178
  for chat in history:
179
+ messages.append({"role": chat["role"], "content": chat["content"]})
 
 
 
180
  messages.append({"role": "user", "content": message})
181
 
 
182
  response = self.openai_client.chat.completions.create(
183
  model="gpt-4o-mini",
184
  messages=messages,
 
186
  max_tokens=150
187
  )
188
 
 
189
  ai_message = response.choices[0].message.content
190
  final_response = ""
191
 
 
192
  parts = ai_message.split("[GIF:")
193
  final_response += parts[0]
194
 
 
201
  final_response += f"\n![GIF]({gif_url})\n"
202
  final_response += part[gif_desc_end + 1:]
203
 
204
+ history.append(self.format_message("user", message))
205
+ history.append(self.format_message("assistant", final_response))
206
  return "", history, ""
207
 
208
  except Exception as error:
209
  error_message = f"Oops! Something went wrong: {str(error)}"
210
  return message, history, error_message
211
 
 
 
 
 
212
  def create_interface():
213
  """Create the Gradio interface"""
214
  bot = GifChatBot()
 
242
  chatbot = gr.Chatbot(
243
  label="Chat",
244
  bubble_full_width=False,
245
+ height=450,
246
+ type="messages" # Use new message format
247
  )
248
 
249
  with gr.Row():
 
274
 
275
  clear_button.click(
276
  bot.reset_chat,
277
+ outputs=[chatbot, error_box]
278
  )
279
 
280
  gr.Markdown("""
 
284
  - 🎯 GIFs are chosen to match the emotion
285
  - 🔄 Use 'Clear Chat' to start fresh
286
  """)
 
 
 
 
 
 
 
287
 
288
  return interface
289
 
290
  if __name__ == "__main__":
291
  demo = create_interface()
292
+ demo.launch()