malek-messaoudii commited on
Commit
8ddb255
·
1 Parent(s): 8791d59

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +106 -76
main.py CHANGED
@@ -37,9 +37,9 @@ def cleanup_temp_files():
37
  if temp_dir.exists():
38
  try:
39
  shutil.rmtree(temp_dir)
40
- logger.info("✓ Cleaned up previous temp audio files")
41
  except Exception as e:
42
- logger.warning(f"⚠ Could not clean temp directory: {e}")
43
 
44
  # Appeler au démarrage
45
  cleanup_temp_files()
@@ -51,36 +51,47 @@ def cleanup_on_exit():
51
  if temp_dir.exists():
52
  try:
53
  shutil.rmtree(temp_dir)
 
54
  except:
55
- pass
56
 
57
  # --- Import des singletons de services ---
58
  try:
59
  from services.stance_model_manager import stance_model_manager
60
- from services.label_model_manager import kpa_model_manager
61
- logger.info("✓ Model managers imported")
62
  except ImportError as e:
63
- logger.warning(f"⚠ Could not import model managers: {e}")
64
  stance_model_manager = None
65
  kpa_model_manager = None
66
 
 
 
 
 
 
 
 
 
 
 
67
  # --- Lifespan / startup API ---
68
  @asynccontextmanager
69
  async def lifespan(app: FastAPI):
70
  logger.info("="*60)
71
- logger.info("🚀 API STARTUP - Loading models and checking APIs...")
72
  logger.info("="*60)
73
 
74
  # Vérifier les clés API
75
  if not GROQ_API_KEY:
76
- logger.warning("⚠ GROQ_API_KEY is not set. STT/TTS features may not work.")
77
  else:
78
- logger.info("✓ GROQ_API_KEY is configured")
79
 
80
  if not HUGGINGFACE_API_KEY:
81
- logger.warning("⚠ HUGGINGFACE_API_KEY is not set. Local models may not work.")
82
  else:
83
- logger.info("✓ HUGGINGFACE_API_KEY is configured")
84
 
85
  # Précharger les modèles Hugging Face si configuré
86
  if PRELOAD_MODELS_ON_STARTUP:
@@ -89,28 +100,37 @@ async def lifespan(app: FastAPI):
89
  if LOAD_STANCE_MODEL and stance_model_manager and HUGGINGFACE_STANCE_MODEL_ID:
90
  try:
91
  stance_model_manager.load_model(HUGGINGFACE_STANCE_MODEL_ID, HUGGINGFACE_API_KEY)
92
- logger.info("✓ Stance model loaded successfully")
93
  except Exception as e:
94
- logger.error(f"✗ Failed loading stance model: {e}")
95
 
96
  # Charger KPA model
97
  if LOAD_KPA_MODEL and kpa_model_manager and HUGGINGFACE_LABEL_MODEL_ID:
98
  try:
99
  kpa_model_manager.load_model(HUGGINGFACE_LABEL_MODEL_ID, HUGGINGFACE_API_KEY)
100
- logger.info("✓ KPA model loaded successfully")
101
  except Exception as e:
102
- logger.error(f"✗ Failed loading KPA model: {e}")
 
 
 
 
 
 
 
 
103
 
104
  logger.info("="*60)
105
- logger.info("✓ Startup complete. API ready to receive requests.")
106
  logger.info(f" STT Model: {GROQ_STT_MODEL}")
107
  logger.info(f" TTS Model: {GROQ_TTS_MODEL}")
108
  logger.info(f" Chat Model: {GROQ_CHAT_MODEL}")
 
109
  logger.info("="*60)
110
 
111
  yield
112
 
113
- logger.info("🛑 Shutting down API...")
114
  # Nettoyage final
115
  cleanup_on_exit()
116
 
@@ -139,64 +159,47 @@ app.add_middleware(
139
  try:
140
  from routes.stt_routes import router as stt_router
141
  app.include_router(stt_router, prefix="/api/v1/stt", tags=["Speech To Text"])
142
- logger.info("✓ STT route loaded (Groq Whisper)")
143
  except ImportError as e:
144
- logger.warning(f"⚠ STT route not found: {e}")
145
  except Exception as e:
146
- logger.warning(f"⚠ Failed loading STT route: {e}")
147
 
148
  # TTS Routes
149
  try:
150
  from routes.tts_routes import router as tts_router
151
  app.include_router(tts_router, prefix="/api/v1/tts", tags=["Text To Speech"])
152
- logger.info("✓ TTS route loaded (Groq PlayAI TTS)")
153
  except ImportError as e:
154
- logger.warning(f"⚠ TTS route not found: {e}")
155
  except Exception as e:
156
- logger.warning(f"⚠ Failed loading TTS route: {e}")
157
 
158
- # Main API Routes
159
- try:
160
- from routes import api_router
161
- app.include_router(api_router)
162
- logger.info("✓ Main API routes loaded")
163
- except ImportError as e:
164
- logger.warning(f"⚠ Main API routes not found: {e}")
165
- except Exception as e:
166
- logger.warning(f"⚠ Failed loading main API routes: {e}")
167
-
168
- # Dans main.py, après les autres routes
169
  try:
170
  from routes.voice_chat_routes import router as voice_chat_router
171
  app.include_router(voice_chat_router, tags=["Voice Chat"])
172
- logger.info("✓ Voice Chat route loaded")
173
  except ImportError as e:
174
- logger.warning(f"⚠ Voice Chat route not found: {e}")
175
  except Exception as e:
176
- logger.warning(f"⚠ Failed loading Voice Chat route: {e}")
177
 
178
- # Dans main.py, après les autres imports
179
  try:
180
- from services.mcp_service import init_mcp_server
181
- from routes.mcp_routes import router as mcp_router
182
- MCP_ENABLED = True
183
  except ImportError as e:
184
- logger.warning(f"⚠ MCP not available: {e}")
185
- MCP_ENABLED = False
 
186
 
187
- # Dans le lifespan manager, après le chargement des modèles
188
  if MCP_ENABLED:
189
- try:
190
- init_mcp_server(app)
191
- logger.info("✓ MCP Server initialized")
192
- except Exception as e:
193
- logger.error(f"✗ MCP initialization failed: {e}")
194
 
195
- # Après les autres routes, ajoutez
196
- if MCP_ENABLED:
197
- app.include_router(mcp_router)
198
- logger.info("✓ MCP routes loaded")
199
-
200
  # --- Basic routes ---
201
  @app.get("/health", tags=["Health"])
202
  async def health():
@@ -204,12 +207,17 @@ async def health():
204
  health_status = {
205
  "status": "healthy",
206
  "service": "NLP Debater + Groq Voice",
 
207
  "features": {
208
  "stt": GROQ_STT_MODEL if GROQ_API_KEY else "disabled",
209
  "tts": GROQ_TTS_MODEL if GROQ_API_KEY else "disabled",
210
  "chat": GROQ_CHAT_MODEL if GROQ_API_KEY else "disabled",
211
- "stance_model": "loaded" if (stance_model_manager and stance_model_manager.model is not None) else "not loaded",
212
- "kpa_model": "loaded" if (kpa_model_manager and kpa_model_manager.model is not None) else "not loaded"
 
 
 
 
213
  }
214
  }
215
  return health_status
@@ -217,42 +225,64 @@ async def health():
217
  @app.get("/", tags=["Root"])
218
  async def root():
219
  """Root endpoint with API information"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  return {
221
- "message": "NLP Debater API with Groq Voice Support",
222
  "version": API_VERSION,
223
- "endpoints": {
224
- "docs": "/docs",
225
- "redoc": "/redoc",
226
- "health": "/health",
227
- "stt": "/api/v1/stt/",
228
- "tts": "/api/v1/tts/"
229
- },
230
  "models": {
231
- "stt": GROQ_STT_MODEL,
232
- "tts": GROQ_TTS_MODEL,
233
- "chat": GROQ_CHAT_MODEL
 
234
  }
235
  }
236
 
237
  # --- Error handlers ---
238
  @app.exception_handler(404)
239
  async def not_found_handler(request, exc):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  return {
241
  "error": "Not Found",
242
- "message": f"The requested URL {request.url} was not found",
243
- "available_endpoints": {
244
- "GET /": "API information",
245
- "GET /health": "Health check",
246
- "POST /api/v1/stt/": "Speech to text",
247
- "POST /api/v1/tts/": "Text to speech"
248
- }
249
  }
250
 
251
  # --- Run server ---
252
  if __name__ == "__main__":
253
  logger.info("="*60)
254
- logger.info(f"Starting server on {HOST}:{PORT}")
255
- logger.info(f"Reload mode: {RELOAD}")
256
  logger.info("="*60)
257
 
258
  uvicorn.run(
 
37
  if temp_dir.exists():
38
  try:
39
  shutil.rmtree(temp_dir)
40
+ logger.info("✓ Fichiers temporaires audio nettoyés")
41
  except Exception as e:
42
+ logger.warning(f"⚠ Impossible de nettoyer le répertoire temporaire: {e}")
43
 
44
  # Appeler au démarrage
45
  cleanup_temp_files()
 
51
  if temp_dir.exists():
52
  try:
53
  shutil.rmtree(temp_dir)
54
+ logger.info("Nettoyage final des fichiers temporaires")
55
  except:
56
+ logger.warning("Échec du nettoyage final")
57
 
58
  # --- Import des singletons de services ---
59
  try:
60
  from services.stance_model_manager import stance_model_manager
61
+ from services.label_model_manager import kpa_model_manager # Corrigé: kpa_model_manager, pas label_model_manager
62
+ logger.info("✓ Gestionnaires de modèles importés")
63
  except ImportError as e:
64
+ logger.warning(f"⚠ Impossible d'importer les gestionnaires de modèles: {e}")
65
  stance_model_manager = None
66
  kpa_model_manager = None
67
 
68
+ # --- Vérification MCP ---
69
+ try:
70
+ from services.mcp_service import init_mcp_server
71
+ from routes.mcp_routes import router as mcp_router
72
+ MCP_ENABLED = True
73
+ logger.info("✓ Modules MCP détectés")
74
+ except ImportError as e:
75
+ logger.warning(f"⚠ MCP non disponible: {e}")
76
+ MCP_ENABLED = False
77
+
78
  # --- Lifespan / startup API ---
79
  @asynccontextmanager
80
  async def lifespan(app: FastAPI):
81
  logger.info("="*60)
82
+ logger.info("🚀 DÉMARRAGE API - Chargement des modèles et vérification des APIs...")
83
  logger.info("="*60)
84
 
85
  # Vérifier les clés API
86
  if not GROQ_API_KEY:
87
+ logger.warning("⚠ GROQ_API_KEY non configurée. Fonctions STT/TTS désactivées.")
88
  else:
89
+ logger.info("✓ GROQ_API_KEY configurée")
90
 
91
  if not HUGGINGFACE_API_KEY:
92
+ logger.warning("⚠ HUGGINGFACE_API_KEY non configurée. Modèles locaux désactivés.")
93
  else:
94
+ logger.info("✓ HUGGINGFACE_API_KEY configurée")
95
 
96
  # Précharger les modèles Hugging Face si configuré
97
  if PRELOAD_MODELS_ON_STARTUP:
 
100
  if LOAD_STANCE_MODEL and stance_model_manager and HUGGINGFACE_STANCE_MODEL_ID:
101
  try:
102
  stance_model_manager.load_model(HUGGINGFACE_STANCE_MODEL_ID, HUGGINGFACE_API_KEY)
103
+ logger.info("✓ Modèle de détection de stance chargé")
104
  except Exception as e:
105
+ logger.error(f"✗ Échec chargement modèle stance: {e}")
106
 
107
  # Charger KPA model
108
  if LOAD_KPA_MODEL and kpa_model_manager and HUGGINGFACE_LABEL_MODEL_ID:
109
  try:
110
  kpa_model_manager.load_model(HUGGINGFACE_LABEL_MODEL_ID, HUGGINGFACE_API_KEY)
111
+ logger.info("✓ Modèle KPA chargé")
112
  except Exception as e:
113
+ logger.error(f"✗ Échec chargement modèle KPA: {e}")
114
+
115
+ # Initialiser MCP si disponible
116
+ if MCP_ENABLED:
117
+ try:
118
+ init_mcp_server(app)
119
+ logger.info("✓ Serveur MCP initialisé")
120
+ except Exception as e:
121
+ logger.error(f"✗ Échec initialisation MCP: {e}")
122
 
123
  logger.info("="*60)
124
+ logger.info("✓ Démarrage terminé. API prête à recevoir des requêtes.")
125
  logger.info(f" STT Model: {GROQ_STT_MODEL}")
126
  logger.info(f" TTS Model: {GROQ_TTS_MODEL}")
127
  logger.info(f" Chat Model: {GROQ_CHAT_MODEL}")
128
+ logger.info(f" MCP: {'Activé' if MCP_ENABLED else 'Désactivé'}")
129
  logger.info("="*60)
130
 
131
  yield
132
 
133
+ logger.info("🛑 Arrêt de l'API...")
134
  # Nettoyage final
135
  cleanup_on_exit()
136
 
 
159
  try:
160
  from routes.stt_routes import router as stt_router
161
  app.include_router(stt_router, prefix="/api/v1/stt", tags=["Speech To Text"])
162
+ logger.info("✓ Route STT chargée (Groq Whisper)")
163
  except ImportError as e:
164
+ logger.warning(f"⚠ Route STT non trouvée: {e}")
165
  except Exception as e:
166
+ logger.warning(f"⚠ Échec chargement route STT: {e}")
167
 
168
  # TTS Routes
169
  try:
170
  from routes.tts_routes import router as tts_router
171
  app.include_router(tts_router, prefix="/api/v1/tts", tags=["Text To Speech"])
172
+ logger.info("✓ Route TTS chargée (Groq PlayAI TTS)")
173
  except ImportError as e:
174
+ logger.warning(f"⚠ Route TTS non trouvée: {e}")
175
  except Exception as e:
176
+ logger.warning(f"⚠ Échec chargement route TTS: {e}")
177
 
178
+ # Voice Chat Routes
 
 
 
 
 
 
 
 
 
 
179
  try:
180
  from routes.voice_chat_routes import router as voice_chat_router
181
  app.include_router(voice_chat_router, tags=["Voice Chat"])
182
+ logger.info("✓ Route Voice Chat chargée")
183
  except ImportError as e:
184
+ logger.warning(f"⚠ Route Voice Chat non trouvée: {e}")
185
  except Exception as e:
186
+ logger.warning(f"⚠ Échec chargement route Voice Chat: {e}")
187
 
188
+ # Main API Routes (KPA, Stance, etc.)
189
  try:
190
+ from routes import api_router
191
+ app.include_router(api_router)
192
+ logger.info("✓ Routes API principales chargées")
193
  except ImportError as e:
194
+ logger.warning(f"⚠ Routes API principales non trouvées: {e}")
195
+ except Exception as e:
196
+ logger.warning(f"⚠ Échec chargement routes API principales: {e}")
197
 
198
+ # MCP Routes
199
  if MCP_ENABLED:
200
+ app.include_router(mcp_router, prefix="/api/v1", tags=["MCP"])
201
+ logger.info("✓ Routes MCP chargées")
 
 
 
202
 
 
 
 
 
 
203
  # --- Basic routes ---
204
  @app.get("/health", tags=["Health"])
205
  async def health():
 
207
  health_status = {
208
  "status": "healthy",
209
  "service": "NLP Debater + Groq Voice",
210
+ "version": API_VERSION,
211
  "features": {
212
  "stt": GROQ_STT_MODEL if GROQ_API_KEY else "disabled",
213
  "tts": GROQ_TTS_MODEL if GROQ_API_KEY else "disabled",
214
  "chat": GROQ_CHAT_MODEL if GROQ_API_KEY else "disabled",
215
+ "stance_model": "loaded" if (stance_model_manager and hasattr(stance_model_manager, 'model_loaded') and stance_model_manager.model_loaded) else "not loaded",
216
+ "kpa_model": "loaded" if (kpa_model_manager and hasattr(kpa_model_manager, 'model_loaded') and kpa_model_manager.model_loaded) else "not loaded",
217
+ "mcp": "enabled" if MCP_ENABLED else "disabled"
218
+ },
219
+ "endpoints": {
220
+ "mcp": "/api/v1/mcp" if MCP_ENABLED else "disabled"
221
  }
222
  }
223
  return health_status
 
225
  @app.get("/", tags=["Root"])
226
  async def root():
227
  """Root endpoint with API information"""
228
+ endpoints = {
229
+ "docs": "/docs",
230
+ "redoc": "/redoc",
231
+ "health": "/health",
232
+ "stt": "/api/v1/stt/",
233
+ "tts": "/api/v1/tts/",
234
+ "voice_chat": "/voice-chat/voice",
235
+ }
236
+
237
+ if MCP_ENABLED:
238
+ endpoints["mcp"] = {
239
+ "health": "/api/v1/mcp/health",
240
+ "tools": "/api/v1/mcp/tools",
241
+ "resources": "/api/v1/mcp/resources",
242
+ "call_tool": "/api/v1/mcp/tools/call"
243
+ }
244
+
245
  return {
246
+ "message": "NLP Debater API avec support vocal Groq et MCP",
247
  "version": API_VERSION,
248
+ "endpoints": endpoints,
 
 
 
 
 
 
249
  "models": {
250
+ "stt": GROQ_STT_MODEL if GROQ_API_KEY else "disabled",
251
+ "tts": GROQ_TTS_MODEL if GROQ_API_KEY else "disabled",
252
+ "chat": GROQ_CHAT_MODEL if GROQ_API_KEY else "disabled",
253
+ "mcp": "enabled" if MCP_ENABLED else "disabled"
254
  }
255
  }
256
 
257
  # --- Error handlers ---
258
  @app.exception_handler(404)
259
  async def not_found_handler(request, exc):
260
+ endpoints = {
261
+ "GET /": "Informations API",
262
+ "GET /health": "Health check",
263
+ "POST /api/v1/stt/": "Speech to text",
264
+ "POST /api/v1/tts/": "Text to speech",
265
+ "POST /voice-chat/voice": "Voice chat"
266
+ }
267
+
268
+ if MCP_ENABLED:
269
+ endpoints.update({
270
+ "GET /api/v1/mcp/health": "Health check MCP",
271
+ "GET /api/v1/mcp/tools": "Liste outils MCP",
272
+ "POST /api/v1/mcp/tools/call": "Appel d'outil MCP"
273
+ })
274
+
275
  return {
276
  "error": "Not Found",
277
+ "message": f"URL {request.url} non trouvée",
278
+ "available_endpoints": endpoints
 
 
 
 
 
279
  }
280
 
281
  # --- Run server ---
282
  if __name__ == "__main__":
283
  logger.info("="*60)
284
+ logger.info(f"Démarrage du serveur sur {HOST}:{PORT}")
285
+ logger.info(f"Mode reload: {RELOAD}")
286
  logger.info("="*60)
287
 
288
  uvicorn.run(