akashpatil8150 commited on
Commit
671d3b1
·
1 Parent(s): e5eecd2

Fix: Migrate to google-genai SDK to resolve gRPC credential errors on HF Spaces

Browse files
Files changed (2) hide show
  1. app.py +44 -92
  2. requirements.txt +1 -1
app.py CHANGED
@@ -4,7 +4,8 @@ import json
4
  import random
5
  import datetime
6
  from typing import Dict, List, Any, Optional
7
- import google.generativeai as genai
 
8
  from dotenv import load_dotenv
9
  import os
10
  import logging
@@ -36,11 +37,10 @@ if not api_key:
36
  logger.error("GEMINI_API_KEY not found in environment variables!")
37
  raise ValueError("GEMINI_API_KEY not found! Please set it in environment variables")
38
 
39
- # Log API key status (without exposing the key)
40
  logger.info(f"API Key loaded successfully (length: {len(api_key)} characters)")
41
 
42
  try:
43
- genai.configure(api_key=api_key)
44
  logger.info("Gemini API configured successfully")
45
  except Exception as e:
46
  logger.error(f"Failed to configure Gemini API: {str(e)}")
@@ -60,16 +60,14 @@ Tools: book_appointment(name,address,date,time), cancel_appointment(id)
60
 
61
  Brief answers only.'''
62
 
63
- model = genai.GenerativeModel(
64
- "models/gemini-flash-lite-latest",
65
- generation_config={
66
- "temperature": 0.2, # Very low for fastest responses
67
- "top_p": 0.8,
68
- "top_k": 5, # Minimal choices for speed
69
- "max_output_tokens": 100, # Very short responses
70
- }
71
- )
72
 
 
 
 
 
 
 
73
  # Tool Functions
74
  def validate_time_slot(time: str) -> tuple[bool, str]:
75
  """Validate if time slot is within business hours and in correct format"""
@@ -216,120 +214,74 @@ def process_tool_call(response_text: str) -> Optional[Dict[str, Any]]:
216
  }
217
 
218
  def chat(user_input: str) -> Dict[str, Any]:
219
- """Main chat function with optimized timeout"""
220
  try:
221
  logger.info(f"Processing chat request: {user_input[:50]}...")
222
  full_prompt = f"{SYSTEM_PROMPT}\n\nUser: {user_input}\n\nAssistant:"
223
-
224
- # Single attempt with very short timeout for speed
225
- response = model.generate_content(
226
- full_prompt,
227
- request_options={"timeout": 10}
228
  )
229
-
230
- # Better response handling
231
- if not response.candidates:
232
- logger.warning("No response candidates generated")
233
  return {
234
  "type": "error",
235
  "content": "No response generated. Please try again.",
236
  "language": "en"
237
  }
238
-
239
- candidate = response.candidates[0]
240
-
241
- # Check if response was blocked or empty
242
- if not candidate.content or not candidate.content.parts:
243
- logger.warning("Response blocked or empty")
244
- return {
245
- "type": "error",
246
- "content": "Response blocked or empty. Please rephrase your question.",
247
- "language": "en"
248
- }
249
-
250
- response_text = candidate.content.parts[0].text.strip()
251
  processed_response = process_tool_call(response_text)
252
  logger.info("Chat request processed successfully")
253
  return processed_response
254
-
255
  except Exception as e:
256
  error_msg = str(e)
257
  logger.error(f"Chat error: {error_msg}")
258
  if "429" in error_msg or "quota" in error_msg.lower():
259
- return {
260
- "type": "error",
261
- "content": "API quota exceeded. Please wait and try again.",
262
- "language": "en"
263
- }
264
- elif "504" in error_msg or "deadline" in error_msg.lower() or "timeout" in error_msg.lower():
265
- return {
266
- "type": "error",
267
- "content": "Response too slow. Try a shorter question or wait a moment.",
268
- "language": "en"
269
- }
270
  else:
271
- return {
272
- "type": "error",
273
- "content": f"Error: {error_msg}",
274
- "language": "en"
275
- }
276
 
277
  def chat_stream(user_input: str):
278
- """Streaming chat function for real-time responses"""
279
  try:
280
  logger.info(f"Processing streaming chat request: {user_input[:50]}...")
281
  full_prompt = f"{SYSTEM_PROMPT}\n\nUser: {user_input}\n\nAssistant:"
282
-
283
- response = model.generate_content(
284
- full_prompt,
285
- stream=True,
286
- request_options={"timeout": 10}
287
- )
288
-
289
  accumulated_text = ""
290
- for chunk in response:
291
- if chunk.candidates and chunk.candidates[0].content.parts:
292
- text = chunk.candidates[0].content.parts[0].text
293
- if text:
294
- accumulated_text += text
295
- yield f"data: {json.dumps({'chunk': text})}\n\n"
296
-
297
- # Process complete response for tool calls
 
298
  if accumulated_text:
299
  processed = process_tool_call(accumulated_text)
300
  yield f"data: {json.dumps({'done': True, 'result': processed})}\n\n"
301
  logger.info("Streaming chat request completed successfully")
302
  else:
303
- error_response = {
304
- "type": "error",
305
- "content": "No response generated. Please try again.",
306
- "language": "en"
307
- }
308
- yield f"data: {json.dumps({'done': True, 'result': error_response})}\n\n"
309
  logger.warning("Streaming chat generated no response")
310
-
311
  except Exception as e:
312
  error_msg = str(e)
313
  logger.error(f"Streaming chat error: {error_msg}")
314
  if "429" in error_msg or "quota" in error_msg.lower():
315
- error_response = {
316
- "type": "error",
317
- "content": "API quota exceeded. Please wait and try again.",
318
- "language": "en"
319
- }
320
- elif "504" in error_msg or "deadline" in error_msg.lower() or "timeout" in error_msg.lower():
321
- error_response = {
322
- "type": "error",
323
- "content": "Response too slow. Try a shorter question or wait a moment.",
324
- "language": "en"
325
- }
326
  else:
327
- error_response = {
328
- "type": "error",
329
- "content": f"Error: {error_msg}",
330
- "language": "en"
331
- }
332
- yield f"data: {json.dumps({'done': True, 'result': error_response})}\n\n"
333
 
334
  # Routes
335
  @app.route('/')
 
4
  import random
5
  import datetime
6
  from typing import Dict, List, Any, Optional
7
+ from google import genai
8
+ from google.genai import types
9
  from dotenv import load_dotenv
10
  import os
11
  import logging
 
37
  logger.error("GEMINI_API_KEY not found in environment variables!")
38
  raise ValueError("GEMINI_API_KEY not found! Please set it in environment variables")
39
 
 
40
  logger.info(f"API Key loaded successfully (length: {len(api_key)} characters)")
41
 
42
  try:
43
+ client = genai.Client(api_key=api_key)
44
  logger.info("Gemini API configured successfully")
45
  except Exception as e:
46
  logger.error(f"Failed to configure Gemini API: {str(e)}")
 
60
 
61
  Brief answers only.'''
62
 
63
+ MODEL_NAME = "gemini-2.0-flash-lite"
 
 
 
 
 
 
 
 
64
 
65
+ GENERATION_CONFIG = types.GenerateContentConfig(
66
+ temperature=0.2,
67
+ top_p=0.8,
68
+ top_k=5,
69
+ max_output_tokens=100,
70
+ )
71
  # Tool Functions
72
  def validate_time_slot(time: str) -> tuple[bool, str]:
73
  """Validate if time slot is within business hours and in correct format"""
 
214
  }
215
 
216
  def chat(user_input: str) -> Dict[str, Any]:
217
+ """Main chat function using new google-genai SDK"""
218
  try:
219
  logger.info(f"Processing chat request: {user_input[:50]}...")
220
  full_prompt = f"{SYSTEM_PROMPT}\n\nUser: {user_input}\n\nAssistant:"
221
+
222
+ response = client.models.generate_content(
223
+ model=MODEL_NAME,
224
+ contents=full_prompt,
225
+ config=GENERATION_CONFIG,
226
  )
227
+
228
+ if not response.text:
229
+ logger.warning("Empty response from Gemini")
 
230
  return {
231
  "type": "error",
232
  "content": "No response generated. Please try again.",
233
  "language": "en"
234
  }
235
+
236
+ response_text = response.text.strip()
 
 
 
 
 
 
 
 
 
 
 
237
  processed_response = process_tool_call(response_text)
238
  logger.info("Chat request processed successfully")
239
  return processed_response
240
+
241
  except Exception as e:
242
  error_msg = str(e)
243
  logger.error(f"Chat error: {error_msg}")
244
  if "429" in error_msg or "quota" in error_msg.lower():
245
+ return {"type": "error", "content": "API quota exceeded. Please wait and try again.", "language": "en"}
246
+ elif "timeout" in error_msg.lower() or "deadline" in error_msg.lower():
247
+ return {"type": "error", "content": "Response too slow. Try a shorter question.", "language": "en"}
 
 
 
 
 
 
 
 
248
  else:
249
+ return {"type": "error", "content": f"Error: {error_msg}", "language": "en"}
 
 
 
 
250
 
251
  def chat_stream(user_input: str):
252
+ """Streaming chat function using new google-genai SDK"""
253
  try:
254
  logger.info(f"Processing streaming chat request: {user_input[:50]}...")
255
  full_prompt = f"{SYSTEM_PROMPT}\n\nUser: {user_input}\n\nAssistant:"
256
+
 
 
 
 
 
 
257
  accumulated_text = ""
258
+ for chunk in client.models.generate_content_stream(
259
+ model=MODEL_NAME,
260
+ contents=full_prompt,
261
+ config=GENERATION_CONFIG,
262
+ ):
263
+ if chunk.text:
264
+ accumulated_text += chunk.text
265
+ yield f"data: {json.dumps({'chunk': chunk.text})}\n\n"
266
+
267
  if accumulated_text:
268
  processed = process_tool_call(accumulated_text)
269
  yield f"data: {json.dumps({'done': True, 'result': processed})}\n\n"
270
  logger.info("Streaming chat request completed successfully")
271
  else:
272
+ yield f"data: {json.dumps({'done': True, 'result': {'type': 'error', 'content': 'No response generated.', 'language': 'en'}})}\n\n"
 
 
 
 
 
273
  logger.warning("Streaming chat generated no response")
274
+
275
  except Exception as e:
276
  error_msg = str(e)
277
  logger.error(f"Streaming chat error: {error_msg}")
278
  if "429" in error_msg or "quota" in error_msg.lower():
279
+ content = "API quota exceeded. Please wait and try again."
280
+ elif "timeout" in error_msg.lower() or "deadline" in error_msg.lower():
281
+ content = "Response too slow. Try a shorter question."
 
 
 
 
 
 
 
 
282
  else:
283
+ content = f"Error: {error_msg}"
284
+ yield f"data: {json.dumps({'done': True, 'result': {'type': 'error', 'content': content, 'language': 'en'}})}\n\n"
 
 
 
 
285
 
286
  # Routes
287
  @app.route('/')
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
  flask==3.1.2
2
  flask-cors==6.0.2
3
- google-generativeai==0.8.6
4
  python-dotenv==1.2.1
5
  gunicorn==23.0.0
 
1
  flask==3.1.2
2
  flask-cors==6.0.2
3
+ google-genai==1.16.0
4
  python-dotenv==1.2.1
5
  gunicorn==23.0.0