adikwok commited on
Commit
b64c343
Β·
verified Β·
1 Parent(s): 7103644

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +218 -118
app.py CHANGED
@@ -3,187 +3,287 @@ import requests
3
  import os
4
  from typing import List, Tuple
5
 
6
- # Multiple API options
7
- APIS = {
8
- "deepseek": {
9
- "url": "https://api.deepseek.com/v1/chat/completions",
10
- "key": os.getenv("DEEPSEEK_API_KEY"),
11
- "model": "deepseek-chat",
12
- "free": False
13
- },
14
- "groq": {
15
- "url": "https://api.groq.com/openai/v1/chat/completions",
16
- "key": os.getenv("GROQ_API_KEY"),
17
- "model": "llama3-8b-8192", # Free tier available
18
- "free": True
19
- },
20
- "together": {
21
- "url": "https://api.together.xyz/v1/chat/completions",
22
- "key": os.getenv("TOGETHER_API_KEY"),
23
- "model": "meta-llama/Llama-2-7b-chat-hf",
24
- "free": True # $5 free credit
25
- },
26
- "openrouter": {
27
- "url": "https://openrouter.ai/api/v1/chat/completions",
28
- "key": os.getenv("OPENROUTER_API_KEY"),
29
- "model": "google/gemma-7b-it:free", # Free model
30
- "free": True
31
- }
32
  }
33
 
34
- def query_api(message: str, history: List[Tuple[str, str]], api_choice: str) -> str:
35
- """Query selected API with error handling"""
36
-
37
- if api_choice not in APIS:
38
- return f"❌ Unknown API: {api_choice}"
39
-
40
- config = APIS[api_choice]
 
 
 
41
 
42
- if not config["key"]:
43
- return f"❌ **API Key Missing for {api_choice.upper()}**\n\nSet environment variable: `{api_choice.upper()}_API_KEY`"
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  try:
46
- # Build messages
47
- messages = [{"role": "system", "content": "You are a helpful assistant."}]
 
 
48
  for user_msg, bot_msg in history:
49
  if user_msg and bot_msg:
50
  messages.extend([
51
  {"role": "user", "content": user_msg},
52
  {"role": "assistant", "content": bot_msg}
53
  ])
 
 
54
  messages.append({"role": "user", "content": message})
55
 
56
- headers = {
57
- "Authorization": f"Bearer {config['key']}",
58
- "Content-Type": "application/json"
59
- }
60
-
61
- # Add special headers for some APIs
62
- if api_choice == "openrouter":
63
- headers["HTTP-Referer"] = "https://your-app.com"
64
- headers["X-Title"] = "Gradio Chat"
65
-
66
  response = requests.post(
67
- config["url"],
68
  headers=headers,
69
  json={
70
- "model": config["model"],
71
  "messages": messages,
72
  "temperature": 0.7,
73
- "max_tokens": 1024
 
 
74
  },
75
  timeout=30
76
  )
77
 
78
- # Handle different error codes
79
  if response.status_code == 401:
80
- return f"❌ **Authentication Error ({api_choice})**\nInvalid API key"
81
- elif response.status_code == 402:
82
- return f"πŸ’³ **Payment Required ({api_choice})**\nAccount needs billing setup or credits"
83
  elif response.status_code == 403:
84
- return f"❌ **Access Denied ({api_choice})**\nPermission denied or quota exceeded"
85
  elif response.status_code == 429:
86
- return f"❌ **Rate Limited ({api_choice})**\nToo many requests, please wait"
87
- elif response.status_code >= 500:
88
- return f"❌ **Server Error ({api_choice})**\nAPI server error, try again later"
 
 
89
 
90
  response.raise_for_status()
 
 
91
  result = response.json()
92
 
93
  if "choices" in result and len(result["choices"]) > 0:
94
- return result["choices"][0]["message"]["content"]
 
95
  else:
96
- return f"❌ **No Response from {api_choice}**\n```json\n{result}\n```"
97
 
98
  except requests.exceptions.Timeout:
99
- return f"❌ **Timeout ({api_choice})**\nRequest took too long"
 
 
 
 
100
  except Exception as e:
101
- return f"❌ **Error ({api_choice})**\n{str(e)}"
102
 
103
- def get_available_apis():
104
- """Get list of APIs with their status"""
105
- available = []
106
- for name, config in APIS.items():
107
- status = "🟒" if config["key"] else "πŸ”΄"
108
- free_tag = " (FREE)" if config["free"] else " (PAID)"
109
- available.append(f"{status} {name.upper()}{free_tag}")
110
- return available
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- def create_interface():
113
- available_apis = get_available_apis()
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
- with gr.Blocks(title="Multi-API Chat", theme=gr.themes.Soft()) as demo:
116
- gr.Markdown("# πŸ€– Multi-API Chat Interface")
117
- gr.Markdown("**Available APIs:**\n" + "\n".join([f"- {api}" for api in available_apis]))
 
 
 
 
 
 
 
 
 
 
 
 
118
 
 
119
  with gr.Row():
120
- api_choice = gr.Dropdown(
121
- choices=list(APIS.keys()),
122
- value="groq", # Default to free option
123
- label="Select API",
124
- info="Choose your AI API provider"
125
  )
126
 
127
- chatbot = gr.Chatbot(label="Conversation", height=500)
 
 
 
 
 
 
128
 
 
129
  with gr.Row():
130
- msg = gr.Textbox(
131
- label="Message",
132
- placeholder="Type your message...",
133
- scale=4
 
 
134
  )
135
- send_btn = gr.Button("Send πŸ“€", variant="primary")
136
-
137
- clear_btn = gr.Button("Clear Chat πŸ—‘οΈ")
138
 
139
- def respond(message: str, chat_history: List[List[str]], api: str):
 
 
 
 
 
140
  if not message.strip():
141
  return "", chat_history
142
 
 
143
  history_tuples = [(h[0], h[1]) for h in chat_history if len(h) >= 2]
144
- bot_message = query_api(message.strip(), history_tuples, api)
 
 
 
 
145
  chat_history.append([message, bot_message])
146
  return "", chat_history
147
 
148
  # Event handlers
149
- msg.submit(respond, [msg, chatbot, api_choice], [msg, chatbot])
150
- send_btn.click(respond, [msg, chatbot, api_choice], [msg, chatbot])
151
- clear_btn.click(lambda: [], None, chatbot)
 
 
 
 
 
 
 
 
 
 
 
152
 
153
- # Examples
154
  gr.Examples(
155
  examples=[
156
- ["Hello! How are you?"],
157
- ["Explain machine learning simply"],
158
- ["Write a Python function to reverse a string"],
159
- ["What's the difference between AI and ML?"]
 
 
 
 
160
  ],
161
- inputs=msg
 
162
  )
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  gr.Markdown("""
165
  ---
166
- ## πŸ”§ Setup Instructions:
167
-
168
- **Free Options (Recommended for testing):**
169
- 1. **Groq** (Free): Get API key at [console.groq.com](https://console.groq.com)
170
- 2. **Together** (Free $5): Get key at [api.together.xyz](https://api.together.xyz)
171
- 3. **OpenRouter** (Free models): Get key at [openrouter.ai](https://openrouter.ai)
172
-
173
- **Paid Options:**
174
- 4. **DeepSeek** (Paid): Needs billing setup at [platform.deepseek.com](https://platform.deepseek.com)
175
-
176
- **Set Environment Variables:**
177
- ```bash
178
- export GROQ_API_KEY="your-key"
179
- export TOGETHER_API_KEY="your-key"
180
- export OPENROUTER_API_KEY="your-key"
181
- export DEEPSEEK_API_KEY="your-key"
182
- ```
183
  """)
184
 
185
  return demo
186
 
 
187
  if __name__ == "__main__":
188
- app = create_interface()
189
- app.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
 
 
 
3
  import os
4
  from typing import List, Tuple
5
 
6
+ # Groq API Configuration
7
+ API_URL = "https://api.groq.com/openai/v1/chat/completions"
8
+ API_KEY = os.getenv("GROQ_API_KEY") # This will read from HF Secrets
9
+
10
+ # Debug info (will show in HF Spaces logs)
11
+ print(f"πŸ”‘ Groq API Key Status: {'βœ… Found' if API_KEY else '❌ Missing'}")
12
+ if API_KEY:
13
+ print(f"πŸ”‘ API Key Preview: {API_KEY[:8]}...")
14
+
15
+ headers = {
16
+ "Authorization": f"Bearer {API_KEY}",
17
+ "Content-Type": "application/json"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
+ # Groq Models
21
+ MODELS = {
22
+ "llama3-8b-8192": "Llama 3 8B ⚑ (Fastest)",
23
+ "llama3-70b-8192": "Llama 3 70B 🧠 (Smartest)",
24
+ "mixtral-8x7b-32768": "Mixtral 8x7B βš–οΈ (Balanced)",
25
+ "gemma-7b-it": "Gemma 7B πŸ” (Google)"
26
+ }
27
+
28
+ def query_groq(message: str, history: List[Tuple[str, str]], model: str) -> str:
29
+ """Query Groq API with comprehensive error handling"""
30
 
31
+ # Check API key
32
+ if not API_KEY:
33
+ return """❌ **API Key Not Found**
34
+
35
+ Please set up your API key in Hugging Face Spaces:
36
+
37
+ 1. Go to your Space's **Settings**
38
+ 2. Click **Repository secrets**
39
+ 3. Add new secret:
40
+ - Name: `GROQ_API_KEY`
41
+ - Value: Your Groq API key
42
+ 4. Restart the Space
43
+
44
+ Get your free API key at: [console.groq.com](https://console.groq.com)"""
45
 
46
  try:
47
+ # Build conversation history
48
+ messages = [{"role": "system", "content": "You are a helpful AI assistant powered by Groq's lightning-fast inference."}]
49
+
50
+ # Add chat history
51
  for user_msg, bot_msg in history:
52
  if user_msg and bot_msg:
53
  messages.extend([
54
  {"role": "user", "content": user_msg},
55
  {"role": "assistant", "content": bot_msg}
56
  ])
57
+
58
+ # Add current message
59
  messages.append({"role": "user", "content": message})
60
 
61
+ # Make API request
 
 
 
 
 
 
 
 
 
62
  response = requests.post(
63
+ API_URL,
64
  headers=headers,
65
  json={
66
+ "model": model,
67
  "messages": messages,
68
  "temperature": 0.7,
69
+ "max_tokens": 2048,
70
+ "stream": False,
71
+ "stop": None
72
  },
73
  timeout=30
74
  )
75
 
76
+ # Handle HTTP errors
77
  if response.status_code == 401:
78
+ return "❌ **Authentication Failed**\nInvalid API key. Please check your GROQ_API_KEY secret."
 
 
79
  elif response.status_code == 403:
80
+ return "❌ **Access Forbidden**\nAPI key doesn't have permission."
81
  elif response.status_code == 429:
82
+ return "❌ **Rate Limited**\nToo many requests. Groq has generous limits, this should be rare."
83
+ elif response.status_code == 500:
84
+ return "❌ **Server Error**\nGroq server issue. Please try again."
85
+ elif response.status_code == 503:
86
+ return "❌ **Service Unavailable**\nGroq is temporarily down. Try again in a moment."
87
 
88
  response.raise_for_status()
89
+
90
+ # Parse response
91
  result = response.json()
92
 
93
  if "choices" in result and len(result["choices"]) > 0:
94
+ content = result["choices"][0]["message"]["content"]
95
+ return content.strip()
96
  else:
97
+ return f"❌ **Unexpected Response Format**\n```json\n{result}\n```"
98
 
99
  except requests.exceptions.Timeout:
100
+ return "❌ **Timeout**\nRequest took too long (>30s). Try again."
101
+ except requests.exceptions.ConnectionError:
102
+ return "❌ **Connection Error**\nCannot connect to Groq API. Check internet connection."
103
+ except requests.exceptions.RequestException as e:
104
+ return f"❌ **Request Error**\n{str(e)}"
105
  except Exception as e:
106
+ return f"❌ **Unexpected Error**\n{str(e)}"
107
 
108
+ def test_api_connection():
109
+ """Test API connection and return status"""
110
+ if not API_KEY:
111
+ return "πŸ”΄ API Key Missing"
112
+
113
+ try:
114
+ response = requests.post(
115
+ API_URL,
116
+ headers=headers,
117
+ json={
118
+ "model": "llama3-8b-8192",
119
+ "messages": [{"role": "user", "content": "test"}],
120
+ "max_tokens": 5
121
+ },
122
+ timeout=10
123
+ )
124
+
125
+ if response.status_code == 200:
126
+ return "🟒 Connected Successfully"
127
+ else:
128
+ return f"πŸ”΄ HTTP {response.status_code}"
129
+ except Exception as e:
130
+ return f"πŸ”΄ Connection Failed: {str(e)[:50]}"
131
 
132
+ def create_gradio_interface():
133
+ # Test connection at startup
134
+ connection_status = test_api_connection()
135
+
136
+ # Custom CSS for better UI
137
+ css = """
138
+ .gradio-container {
139
+ max-width: 800px !important;
140
+ margin: auto !important;
141
+ }
142
+ .chat-message {
143
+ padding: 10px !important;
144
+ }
145
+ """
146
 
147
+ with gr.Blocks(
148
+ title="⚑ Groq AI Chat",
149
+ theme=gr.themes.Soft(primary_hue="blue"),
150
+ css=css
151
+ ) as demo:
152
+
153
+ # Header
154
+ gr.Markdown("""
155
+ # ⚑ Groq AI Chat
156
+ ### Lightning-fast AI responses powered by Groq's LPUβ„’
157
+ """)
158
+
159
+ # Status indicator
160
+ with gr.Row():
161
+ gr.Markdown(f"**Connection Status:** {connection_status}")
162
 
163
+ # Model selector
164
  with gr.Row():
165
+ model_dropdown = gr.Dropdown(
166
+ choices=list(MODELS.keys()),
167
+ value="llama3-8b-8192",
168
+ label="πŸ€– Select AI Model",
169
+ info="Choose the model that best fits your needs"
170
  )
171
 
172
+ # Chat interface
173
+ chatbot = gr.Chatbot(
174
+ label="πŸ’¬ Chat History",
175
+ height=500,
176
+ bubble_full_width=False,
177
+ show_copy_button=True
178
+ )
179
 
180
+ # Input area
181
  with gr.Row():
182
+ msg_textbox = gr.Textbox(
183
+ label="✍️ Your Message",
184
+ placeholder="Ask me anything... Groq responses are incredibly fast!",
185
+ scale=4,
186
+ lines=2,
187
+ max_lines=5
188
  )
189
+ send_button = gr.Button("Send ⚑", variant="primary", scale=1)
 
 
190
 
191
+ # Control buttons
192
+ with gr.Row():
193
+ clear_button = gr.Button("πŸ—‘οΈ Clear Chat", variant="secondary")
194
+
195
+ # Chat logic
196
+ def respond(message: str, chat_history: List[List[str]], model: str):
197
  if not message.strip():
198
  return "", chat_history
199
 
200
+ # Convert gradio format to API format
201
  history_tuples = [(h[0], h[1]) for h in chat_history if len(h) >= 2]
202
+
203
+ # Get AI response
204
+ bot_message = query_groq(message.strip(), history_tuples, model)
205
+
206
+ # Update chat history
207
  chat_history.append([message, bot_message])
208
  return "", chat_history
209
 
210
  # Event handlers
211
+ msg_textbox.submit(
212
+ respond,
213
+ inputs=[msg_textbox, chatbot, model_dropdown],
214
+ outputs=[msg_textbox, chatbot]
215
+ )
216
+ send_button.click(
217
+ respond,
218
+ inputs=[msg_textbox, chatbot, model_dropdown],
219
+ outputs=[msg_textbox, chatbot]
220
+ )
221
+ clear_button.click(
222
+ lambda: [],
223
+ outputs=chatbot
224
+ )
225
 
226
+ # Example prompts
227
  gr.Examples(
228
  examples=[
229
+ ["Hello! What makes Groq special?"],
230
+ ["Explain quantum computing in simple terms"],
231
+ ["Write a Python function to find prime numbers"],
232
+ ["What's the difference between AI, ML, and Deep Learning?"],
233
+ ["Help me debug this error: 'TypeError: 'str' object is not callable'"],
234
+ ["Create a simple REST API with FastAPI"],
235
+ ["Explain the concept of recursion with examples"],
236
+ ["What are the latest trends in web development?"]
237
  ],
238
+ inputs=msg_textbox,
239
+ label="πŸ’‘ Try these examples:"
240
  )
241
 
242
+ # Information accordion
243
+ with gr.Accordion("ℹ️ About Groq & Models", open=False):
244
+ gr.Markdown(f"""
245
+ **πŸš€ Why Groq is Amazing:**
246
+ - ⚑ **Fastest AI inference** in the world (500+ tokens/second)
247
+ - πŸ†“ **Generous free tier** with high rate limits
248
+ - πŸ”„ **Real-time responses** feel like magic
249
+ - 🎯 **Consistent quality** across all models
250
+
251
+ **πŸ€– Available Models:**
252
+ {chr(10).join([f"- **{model}**: {desc}" for model, desc in MODELS.items()])}
253
+
254
+ **πŸ”§ Technical Details:**
255
+ - Powered by Groq's custom LPUβ„’ (Language Processing Unit)
256
+ - Optimized for transformer model inference
257
+ - Supports context windows up to 32K tokens
258
+ - Enterprise-grade reliability and security
259
+ """)
260
+
261
+ # Footer
262
  gr.Markdown("""
263
  ---
264
+ **πŸ”‘ Setup Instructions:**
265
+ 1. Get free API key: [console.groq.com](https://console.groq.com)
266
+ 2. Add to HF Spaces: Settings β†’ Repository secrets β†’ `GROQ_API_KEY`
267
+ 3. Restart your Space and enjoy lightning-fast AI!
268
+
269
+ **πŸ’‘ Tips:**
270
+ - Groq excels at coding, explanations, and creative tasks
271
+ - Try different models to see which fits your use case
272
+ - The speed difference is immediately noticeable!
 
 
 
 
 
 
 
 
273
  """)
274
 
275
  return demo
276
 
277
+ # Create and launch the interface
278
  if __name__ == "__main__":
279
+ print("πŸš€ Initializing Groq Chat Interface...")
280
+ print(f"πŸ”‘ API Key Status: {'βœ… Ready' if API_KEY else '❌ Please add GROQ_API_KEY to secrets'}")
281
+
282
+ demo = create_gradio_interface()
283
+ demo.launch(
284
+ server_name="0.0.0.0",
285
+ server_port=7860,
286
+ show_error=True,
287
+ show_api=False, # Hide API docs for cleaner interface
288
+ favicon_path=None
289
+ )