# app/main.py from fastapi import FastAPI, UploadFile, File, WebSocket, WebSocketDisconnect from fastapi.middleware.cors import CORSMiddleware from services import stt_service, tts_service, llm_service, live_stream_service # type: ignore import uvicorn app = FastAPI( title="Holokia Avatar Backend", description="Backend pour avatar 3D interactif avec STT, TTS, LLM et LiveKit streaming", version="1.0.0" ) # ✅ Activer CORS pour éviter les blocages côté front app.add_middleware( CORSMiddleware, allow_origins=["*"], # ⚠️ En prod, mettre le domaine du front allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 🩺 Health check @app.get("/health") async def health(): return {"status": "ok", "message": "Backend operational"} # 🎤 STT - Audio → Texte @app.post("/stt/transcribe") async def transcribe_audio(file: UploadFile = File(...)): try: result = await stt_service.transcribe_audio(file) return {"text": result} except Exception as e: return {"error": str(e)} # 🗣 TTS - Texte → Audio @app.post("/tts/generate") async def generate_tts(text: str): try: audio_path = await tts_service.text_to_speech(text) return {"audio_file": audio_path} except Exception as e: return {"error": str(e)} # 🤖 LLM - Prompt → Texte @app.post("/llm/generate") async def generate_llm(prompt: str): try: response = await llm_service.generate_response(prompt) return {"response": response} except Exception as e: return {"error": str(e)} # 📡 Live streaming WebSocket @app.websocket("/live-stream") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() try: await live_stream_service.handle_connection(websocket) except WebSocketDisconnect: print("🔌 Client déconnecté du live stream") except Exception as e: print(f"❌ Erreur WebSocket : {e}") finally: await websocket.close() # 🚀 Point d'entrée if __name__ == "__main__": uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)