Gaston895 commited on
Commit
fb249da
Β·
verified Β·
1 Parent(s): 95fb302

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +86 -93
app.py CHANGED
@@ -11,7 +11,7 @@ import logging
11
  import os
12
  from dotenv import load_dotenv
13
  import random
14
- from huggingface_hub import InferenceClient
15
 
16
  # Load environment variables
17
  load_dotenv()
@@ -38,112 +38,97 @@ GLOBAL_REGIONS = [
38
  # HuggingFace Token for all providers
39
  HF_TOKEN = os.getenv('HF_TOKEN', '')
40
 
41
- # Initialize InferenceClient instances for DeepSeek models using new router endpoint
42
- inference_clients = []
43
  if HF_TOKEN:
44
  try:
45
- # Primary DeepSeek-V3.2-Exp client with new router endpoint
46
- primary_client = InferenceClient(
47
- model="deepseek-ai/DeepSeek-V3.2-Exp",
48
- token=HF_TOKEN,
49
  base_url="https://router.huggingface.co/v1"
50
  )
51
- inference_clients.append({
52
  "name": "deepseek-v3.2-exp",
53
  "client": primary_client,
54
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
55
  })
56
 
57
- # Secondary DeepSeek-V3-Base client with new router endpoint
58
- secondary_client = InferenceClient(
59
- model="deepseek-ai/DeepSeek-V3-Base",
60
- token=HF_TOKEN,
61
  base_url="https://router.huggingface.co/v1"
62
  )
63
- inference_clients.append({
64
  "name": "deepseek-v3-base",
65
  "client": secondary_client,
66
  "model": "deepseek-ai/DeepSeek-V3-Base"
67
  })
68
 
69
- # Fallback client (same as primary) with new router endpoint
70
- fallback_client = InferenceClient(
71
- model="deepseek-ai/DeepSeek-V3.2-Exp",
72
- token=HF_TOKEN,
73
  base_url="https://router.huggingface.co/v1"
74
  )
75
- inference_clients.append({
76
  "name": "deepseek-fallback",
77
  "client": fallback_client,
78
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
79
  })
80
 
81
  except Exception as e:
82
- logger.error(f"Failed to initialize InferenceClient: {e}")
83
 
84
- # Legacy API_PROVIDERS for compatibility (now using InferenceClient)
85
  API_PROVIDERS = [
86
  {
87
  "name": "deepseek-v3.2-exp",
88
- "provider": "hf_inference_client",
89
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
90
  },
91
  {
92
  "name": "deepseek-v3-base",
93
- "provider": "hf_inference_client",
94
  "model": "deepseek-ai/DeepSeek-V3-Base"
95
  },
96
  {
97
  "name": "deepseek-fallback",
98
- "provider": "hf_inference_client",
99
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
100
  }
101
  ]
102
 
103
  def get_next_provider():
104
- """Get the next available InferenceClient for failover"""
105
  global current_provider_index
106
- if not inference_clients:
107
  return None
108
- client_info = inference_clients[current_provider_index]
109
- current_provider_index = (current_provider_index + 1) % len(inference_clients)
110
  return client_info
111
 
112
  def call_deepseek_api(messages: List[Dict], client_info: Dict, max_retries: int = 3) -> Optional[str]:
113
- """Call DeepSeek API via HuggingFace InferenceClient"""
114
  if not client_info:
115
  return None
116
 
117
  try:
118
  client = client_info["client"]
 
119
 
120
- # Convert messages to a single prompt for text_generation
121
- conversation = ""
122
- for msg in messages:
123
- if msg["role"] == "system":
124
- conversation += f"System: {msg['content']}\n\n"
125
- elif msg["role"] == "user":
126
- conversation += f"User: {msg['content']}\n\n"
127
- elif msg["role"] == "assistant":
128
- conversation += f"Assistant: {msg['content']}\n\n"
129
-
130
- conversation += "Assistant: "
131
-
132
- # Use text_generation method instead of chat_completion
133
- response = client.text_generation(
134
- prompt=conversation,
135
- max_new_tokens=1024,
136
  temperature=0.7,
137
  top_p=0.9,
138
- do_sample=True,
139
- return_full_text=False,
140
  stream=False
141
  )
142
 
143
  # Extract content from response
144
- if isinstance(response, str):
145
- content = response
146
- logger.info(f"βœ… Success with InferenceClient: {client_info['name']} ({client_info['model']})")
147
  return content.strip()
148
  else:
149
  logger.warning(f"⚠️ Unexpected response format from {client_info['name']}: {response}")
@@ -159,30 +144,38 @@ def call_deepseek_api(messages: List[Dict], client_info: Dict, max_retries: int
159
  else:
160
  logger.warning(f"⚠️ API error from {client_info['name']}: {str(e)}")
161
  return None
 
 
 
 
 
 
 
 
162
 
163
  def call_deepseek_with_failover(messages: List[Dict]) -> str:
164
- """Call DeepSeek-V3.2-Exp with automatic InferenceClient failover"""
165
- if not inference_clients:
166
- return "InferenceClient not initialized. Please check HF_TOKEN configuration."
167
 
168
  clients_tried = []
169
 
170
  # Try all clients until one succeeds
171
- for attempt in range(len(inference_clients)):
172
  client_info = get_next_provider()
173
  if not client_info:
174
  continue
175
 
176
  clients_tried.append(client_info['name'])
177
 
178
- logger.info(f"πŸ”„ Trying InferenceClient: {client_info['name']} (attempt {attempt + 1}/{len(inference_clients)})")
179
 
180
  result = call_deepseek_api(messages, client_info)
181
  if result:
182
  return result
183
 
184
  # If all clients failed
185
- logger.error(f"❌ All InferenceClients failed: {', '.join(clients_tried)}")
186
  return f"I apologize, but all API providers ({', '.join(clients_tried)}) are currently unavailable. Please try again in a moment."
187
 
188
  def format_response(text):
@@ -315,7 +308,7 @@ Provide comprehensive analysis with specific numerical values for all calculated
315
  "year": year,
316
  "analysis_timestamp": datetime.now().isoformat(),
317
  "model": MODEL_NAME,
318
- "providers": [c["name"] for c in inference_clients]
319
  }
320
 
321
  # Extract metrics from model response
@@ -371,8 +364,8 @@ def status():
371
  'model': MODEL_NAME,
372
  'version': AEGIS_VERSION,
373
  'regions': len(GLOBAL_REGIONS),
374
- 'providers': [c["name"] for c in inference_clients],
375
- 'current_provider': inference_clients[current_provider_index]["name"] if inference_clients else "none",
376
  'api_ready': True
377
  })
378
 
@@ -405,23 +398,23 @@ def chat():
405
  'provider_status': 'HF_TOKEN missing'
406
  }), 500
407
 
408
- if not inference_clients:
409
- logger.error("InferenceClients not initialized!")
410
  return jsonify({
411
- 'error': 'InferenceClients not initialized. Please check HF_TOKEN configuration.',
412
- 'provider_status': 'InferenceClients not initialized'
413
  }), 500
414
 
415
  # Generate response using AEGIS Multi-Domain System with DeepSeek-V3.2-Exp
416
  logger.info("Generating AEGIS analysis...")
417
  response = analyze_with_aegis_conductor(message, analysis_type)
418
 
419
- if not response or response.startswith("I apologize, but all API providers") or response.startswith("InferenceClient not initialized"):
420
- logger.error("All InferenceClients failed or returned empty response")
421
  return jsonify({
422
  'error': 'All API providers are currently unavailable. Please check your HF_TOKEN and try again.',
423
  'response': response,
424
- 'provider_status': 'All InferenceClients failed'
425
  }), 503
426
 
427
  logger.info(f"Successfully generated response of length: {len(response)}")
@@ -431,10 +424,10 @@ def chat():
431
  'timestamp': time.time(),
432
  'model': f"AEGIS BIO LAB {AEGIS_VERSION} CONDUCTOR (DeepSeek-V3.2-Exp)",
433
  'analysis_type': analysis_type,
434
- 'provider': f"{inference_clients[current_provider_index]['name'] if inference_clients else 'none'} (InferenceClient)",
435
- 'hf_inference_client': True,
436
  'hf_token_configured': bool(HF_TOKEN and len(HF_TOKEN) > 10),
437
- 'clients_initialized': len(inference_clients)
438
  })
439
 
440
  except Exception as e:
@@ -503,16 +496,16 @@ def diagnostic():
503
  <strong>Model:</strong> {MODEL_NAME}
504
  </div>
505
 
506
- <div class="status {'good' if inference_clients else 'bad'}">
507
- <strong>InferenceClients:</strong> {len(inference_clients)} initialized
508
  </div>
509
 
510
  <div class="status good">
511
- <strong>Current Client:</strong> {inference_clients[current_provider_index]["name"] if inference_clients else "none"}
512
  </div>
513
 
514
  <h2>πŸ”§ Configuration Instructions</h2>
515
- <p>Using HuggingFace InferenceClient (only HF_TOKEN required):</p>
516
  <ol>
517
  <li>Go to your space settings</li>
518
  <li>Click "Variables and secrets"</li>
@@ -535,10 +528,10 @@ def provider_status():
535
  """Get status of all InferenceClient providers"""
536
  provider_statuses = []
537
 
538
- for i, client_info in enumerate(inference_clients):
539
  status_info = {
540
  "name": client_info["name"],
541
- "provider_type": "hf_inference_client",
542
  "active": i == current_provider_index,
543
  "model": client_info.get("model", MODEL_NAME),
544
  "has_api_key": bool(HF_TOKEN and len(HF_TOKEN) > 10),
@@ -547,40 +540,40 @@ def provider_status():
547
  provider_statuses.append(status_info)
548
 
549
  # Count available providers
550
- available_providers = len(inference_clients) if HF_TOKEN and len(HF_TOKEN) > 10 else 0
551
 
552
  return jsonify({
553
  "providers": provider_statuses,
554
- "current_provider": inference_clients[current_provider_index]["name"] if inference_clients else "none",
555
- "current_provider_type": "hf_inference_client",
556
- "total_providers": len(inference_clients),
557
  "available_providers": available_providers,
558
  "model": MODEL_NAME,
559
  "api_keys_status": {
560
  "hf_token": bool(HF_TOKEN and len(HF_TOKEN) > 10),
561
- "note": "Using HuggingFace InferenceClient - only HF_TOKEN required"
562
  }
563
  })
564
 
565
  @app.route('/switch_provider', methods=['POST'])
566
  def switch_provider():
567
- """Manually switch to next InferenceClient provider"""
568
  global current_provider_index
569
 
570
- if not inference_clients:
571
  return jsonify({
572
- "error": "No InferenceClients available",
573
  "message": "Please check HF_TOKEN configuration"
574
  }), 500
575
 
576
- old_client = inference_clients[current_provider_index]["name"]
577
- current_provider_index = (current_provider_index + 1) % len(inference_clients)
578
- new_client = inference_clients[current_provider_index]["name"]
579
 
580
  return jsonify({
581
- "switched_from": f"{old_client} (InferenceClient)",
582
- "switched_to": f"{new_client} (InferenceClient)",
583
- "message": f"Switched from {old_client} to {new_client} InferenceClient",
584
  "model": MODEL_NAME
585
  })
586
 
@@ -593,12 +586,12 @@ def initialize_system():
593
  print(f"πŸ€— Model: {MODEL_NAME}")
594
  print(f"πŸ”— Endpoint: https://router.huggingface.co/v1")
595
 
596
- if inference_clients:
597
- client_list = ', '.join([f"{c['name']} ({c['model']})" for c in inference_clients])
598
- print(f"πŸ“‘ Available InferenceClients: {client_list}")
599
- print(f"πŸ”„ Automatic failover enabled across {len(inference_clients)} InferenceClients")
600
  else:
601
- print("❌ No InferenceClients initialized - check HF_TOKEN")
602
 
603
  print(f"🌍 Global analysis across {len(GLOBAL_REGIONS)} regions")
604
  print(f"πŸ”‘ Using HuggingFace Token: {'βœ… Valid' if HF_TOKEN and len(HF_TOKEN) > 10 else '❌ Missing'}")
 
11
  import os
12
  from dotenv import load_dotenv
13
  import random
14
+ from openai import OpenAI
15
 
16
  # Load environment variables
17
  load_dotenv()
 
38
  # HuggingFace Token for all providers
39
  HF_TOKEN = os.getenv('HF_TOKEN', '')
40
 
41
+ # Initialize OpenAI-compatible clients for DeepSeek models using HuggingFace router
42
+ openai_clients = []
43
  if HF_TOKEN:
44
  try:
45
+ # Primary DeepSeek-V3.2-Exp client
46
+ primary_client = OpenAI(
47
+ api_key=HF_TOKEN,
 
48
  base_url="https://router.huggingface.co/v1"
49
  )
50
+ openai_clients.append({
51
  "name": "deepseek-v3.2-exp",
52
  "client": primary_client,
53
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
54
  })
55
 
56
+ # Secondary DeepSeek-V3-Base client
57
+ secondary_client = OpenAI(
58
+ api_key=HF_TOKEN,
 
59
  base_url="https://router.huggingface.co/v1"
60
  )
61
+ openai_clients.append({
62
  "name": "deepseek-v3-base",
63
  "client": secondary_client,
64
  "model": "deepseek-ai/DeepSeek-V3-Base"
65
  })
66
 
67
+ # Fallback client (same as primary)
68
+ fallback_client = OpenAI(
69
+ api_key=HF_TOKEN,
 
70
  base_url="https://router.huggingface.co/v1"
71
  )
72
+ openai_clients.append({
73
  "name": "deepseek-fallback",
74
  "client": fallback_client,
75
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
76
  })
77
 
78
  except Exception as e:
79
+ logger.error(f"Failed to initialize OpenAI clients: {e}")
80
 
81
+ # Legacy API_PROVIDERS for compatibility (now using OpenAI client)
82
  API_PROVIDERS = [
83
  {
84
  "name": "deepseek-v3.2-exp",
85
+ "provider": "hf_router_openai",
86
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
87
  },
88
  {
89
  "name": "deepseek-v3-base",
90
+ "provider": "hf_router_openai",
91
  "model": "deepseek-ai/DeepSeek-V3-Base"
92
  },
93
  {
94
  "name": "deepseek-fallback",
95
+ "provider": "hf_router_openai",
96
  "model": "deepseek-ai/DeepSeek-V3.2-Exp"
97
  }
98
  ]
99
 
100
  def get_next_provider():
101
+ """Get the next available OpenAI client for failover"""
102
  global current_provider_index
103
+ if not openai_clients:
104
  return None
105
+ client_info = openai_clients[current_provider_index]
106
+ current_provider_index = (current_provider_index + 1) % len(openai_clients)
107
  return client_info
108
 
109
  def call_deepseek_api(messages: List[Dict], client_info: Dict, max_retries: int = 3) -> Optional[str]:
110
+ """Call DeepSeek API via HuggingFace Router using OpenAI client"""
111
  if not client_info:
112
  return None
113
 
114
  try:
115
  client = client_info["client"]
116
+ model = client_info["model"]
117
 
118
+ # Use OpenAI client with HuggingFace router
119
+ response = client.chat.completions.create(
120
+ model=model,
121
+ messages=messages,
122
+ max_tokens=1024,
 
 
 
 
 
 
 
 
 
 
 
123
  temperature=0.7,
124
  top_p=0.9,
 
 
125
  stream=False
126
  )
127
 
128
  # Extract content from response
129
+ if response.choices and len(response.choices) > 0:
130
+ content = response.choices[0].message.content
131
+ logger.info(f"βœ… Success with OpenAI client: {client_info['name']} ({client_info['model']})")
132
  return content.strip()
133
  else:
134
  logger.warning(f"⚠️ Unexpected response format from {client_info['name']}: {response}")
 
144
  else:
145
  logger.warning(f"⚠️ API error from {client_info['name']}: {str(e)}")
146
  return None
147
+ if "rate limit" in error_msg or "429" in error_msg:
148
+ logger.warning(f"πŸ’Έ Rate limit reached for {client_info['name']}, switching to next provider...")
149
+ elif "503" in error_msg or "service unavailable" in error_msg:
150
+ logger.warning(f"⏳ Model loading for {client_info['name']}, waiting...")
151
+ time.sleep(10) # Wait for model to load
152
+ else:
153
+ logger.warning(f"⚠️ API error from {client_info['name']}: {str(e)}")
154
+ return None
155
 
156
  def call_deepseek_with_failover(messages: List[Dict]) -> str:
157
+ """Call DeepSeek-V3.2-Exp with automatic OpenAI client failover"""
158
+ if not openai_clients:
159
+ return "OpenAI clients not initialized. Please check HF_TOKEN configuration."
160
 
161
  clients_tried = []
162
 
163
  # Try all clients until one succeeds
164
+ for attempt in range(len(openai_clients)):
165
  client_info = get_next_provider()
166
  if not client_info:
167
  continue
168
 
169
  clients_tried.append(client_info['name'])
170
 
171
+ logger.info(f"πŸ”„ Trying OpenAI client: {client_info['name']} (attempt {attempt + 1}/{len(openai_clients)})")
172
 
173
  result = call_deepseek_api(messages, client_info)
174
  if result:
175
  return result
176
 
177
  # If all clients failed
178
+ logger.error(f"❌ All OpenAI clients failed: {', '.join(clients_tried)}")
179
  return f"I apologize, but all API providers ({', '.join(clients_tried)}) are currently unavailable. Please try again in a moment."
180
 
181
  def format_response(text):
 
308
  "year": year,
309
  "analysis_timestamp": datetime.now().isoformat(),
310
  "model": MODEL_NAME,
311
+ "providers": [c["name"] for c in openai_clients]
312
  }
313
 
314
  # Extract metrics from model response
 
364
  'model': MODEL_NAME,
365
  'version': AEGIS_VERSION,
366
  'regions': len(GLOBAL_REGIONS),
367
+ 'providers': [c["name"] for c in openai_clients],
368
+ 'current_provider': openai_clients[current_provider_index]["name"] if openai_clients else "none",
369
  'api_ready': True
370
  })
371
 
 
398
  'provider_status': 'HF_TOKEN missing'
399
  }), 500
400
 
401
+ if not openai_clients:
402
+ logger.error("OpenAI clients not initialized!")
403
  return jsonify({
404
+ 'error': 'OpenAI clients not initialized. Please check HF_TOKEN configuration.',
405
+ 'provider_status': 'OpenAI clients not initialized'
406
  }), 500
407
 
408
  # Generate response using AEGIS Multi-Domain System with DeepSeek-V3.2-Exp
409
  logger.info("Generating AEGIS analysis...")
410
  response = analyze_with_aegis_conductor(message, analysis_type)
411
 
412
+ if not response or response.startswith("I apologize, but all API providers") or response.startswith("OpenAI clients not initialized"):
413
+ logger.error("All OpenAI clients failed or returned empty response")
414
  return jsonify({
415
  'error': 'All API providers are currently unavailable. Please check your HF_TOKEN and try again.',
416
  'response': response,
417
+ 'provider_status': 'All OpenAI clients failed'
418
  }), 503
419
 
420
  logger.info(f"Successfully generated response of length: {len(response)}")
 
424
  'timestamp': time.time(),
425
  'model': f"AEGIS BIO LAB {AEGIS_VERSION} CONDUCTOR (DeepSeek-V3.2-Exp)",
426
  'analysis_type': analysis_type,
427
+ 'provider': f"{openai_clients[current_provider_index]['name'] if openai_clients else 'none'} (OpenAI)",
428
+ 'hf_router_openai': True,
429
  'hf_token_configured': bool(HF_TOKEN and len(HF_TOKEN) > 10),
430
+ 'clients_initialized': len(openai_clients)
431
  })
432
 
433
  except Exception as e:
 
496
  <strong>Model:</strong> {MODEL_NAME}
497
  </div>
498
 
499
+ <div class="status {'good' if openai_clients else 'bad'}">
500
+ <strong>OpenAI Clients:</strong> {len(openai_clients)} initialized
501
  </div>
502
 
503
  <div class="status good">
504
+ <strong>Current Client:</strong> {openai_clients[current_provider_index]["name"] if openai_clients else "none"}
505
  </div>
506
 
507
  <h2>πŸ”§ Configuration Instructions</h2>
508
+ <p>Using HuggingFace Router with OpenAI client (only HF_TOKEN required):</p>
509
  <ol>
510
  <li>Go to your space settings</li>
511
  <li>Click "Variables and secrets"</li>
 
528
  """Get status of all InferenceClient providers"""
529
  provider_statuses = []
530
 
531
+ for i, client_info in enumerate(openai_clients):
532
  status_info = {
533
  "name": client_info["name"],
534
+ "provider_type": "hf_router_openai",
535
  "active": i == current_provider_index,
536
  "model": client_info.get("model", MODEL_NAME),
537
  "has_api_key": bool(HF_TOKEN and len(HF_TOKEN) > 10),
 
540
  provider_statuses.append(status_info)
541
 
542
  # Count available providers
543
+ available_providers = len(openai_clients) if HF_TOKEN and len(HF_TOKEN) > 10 else 0
544
 
545
  return jsonify({
546
  "providers": provider_statuses,
547
+ "current_provider": openai_clients[current_provider_index]["name"] if openai_clients else "none",
548
+ "current_provider_type": "hf_router_openai",
549
+ "total_providers": len(openai_clients),
550
  "available_providers": available_providers,
551
  "model": MODEL_NAME,
552
  "api_keys_status": {
553
  "hf_token": bool(HF_TOKEN and len(HF_TOKEN) > 10),
554
+ "note": "Using HuggingFace Router with OpenAI client - only HF_TOKEN required"
555
  }
556
  })
557
 
558
  @app.route('/switch_provider', methods=['POST'])
559
  def switch_provider():
560
+ """Manually switch to next OpenAI client provider"""
561
  global current_provider_index
562
 
563
+ if not openai_clients:
564
  return jsonify({
565
+ "error": "No OpenAI clients available",
566
  "message": "Please check HF_TOKEN configuration"
567
  }), 500
568
 
569
+ old_client = openai_clients[current_provider_index]["name"]
570
+ current_provider_index = (current_provider_index + 1) % len(openai_clients)
571
+ new_client = openai_clients[current_provider_index]["name"]
572
 
573
  return jsonify({
574
+ "switched_from": f"{old_client} (OpenAI)",
575
+ "switched_to": f"{new_client} (OpenAI)",
576
+ "message": f"Switched from {old_client} to {new_client} OpenAI client",
577
  "model": MODEL_NAME
578
  })
579
 
 
586
  print(f"πŸ€— Model: {MODEL_NAME}")
587
  print(f"πŸ”— Endpoint: https://router.huggingface.co/v1")
588
 
589
+ if openai_clients:
590
+ client_list = ', '.join([f"{c['name']} ({c['model']})" for c in openai_clients])
591
+ print(f"πŸ“‘ Available OpenAI clients: {client_list}")
592
+ print(f"πŸ”„ Automatic failover enabled across {len(openai_clients)} OpenAI clients")
593
  else:
594
+ print("❌ No OpenAI clients initialized - check HF_TOKEN")
595
 
596
  print(f"🌍 Global analysis across {len(GLOBAL_REGIONS)} regions")
597
  print(f"πŸ”‘ Using HuggingFace Token: {'βœ… Valid' if HF_TOKEN and len(HF_TOKEN) > 10 else '❌ Missing'}")