from fastapi import FastAPI, File, UploadFile, HTTPException from allosaurus.app import read_recognizer from contextlib import asynccontextmanager import aiofiles import os import uuid # Variable globale pour stocker le modèle en mémoire ai_context = {} @asynccontextmanager async def lifespan(app: FastAPI): print("🚀 Démarrage de l'API...") try: # On charge le modèle en RAM. C'est très rapide car il est déjà sur le disque. ai_context["model"] = read_recognizer() print("✅ Allosaurus est chargé et prêt !") except Exception as e: print(f"❌ Erreur au chargement : {e}") yield ai_context.clear() app = FastAPI(lifespan=lifespan) @app.get("/") def home(): return {"status": "En ligne", "info": "Envoie un fichier audio POST sur /transcribe"} @app.post("/transcribe") async def transcribe(file: UploadFile = File(...)): # Vérifier que le modèle est bien là if "model" not in ai_context: raise HTTPException(status_code=500, detail="Le modèle n'est pas chargé.") # 1. Créer un nom de fichier temporaire unique temp_filename = f"temp_{uuid.uuid4()}.wav" try: # 2. Sauvegarder le fichier reçu sur le disque du serveur async with aiofiles.open(temp_filename, 'wb') as out_file: content = await file.read() await out_file.write(content) # 3. Lancer la reconnaissance model = ai_context["model"] # 'fra' force le modèle à utiliser l'inventaire phonétique français phonemes = model.recognize(temp_filename, lang_id='fra') return { "ipa": phonemes, "filename": file.filename } except Exception as e: print(f"Erreur : {e}") raise HTTPException(status_code=500, detail=str(e)) finally: # 4. Nettoyage : Toujours supprimer le fichier temporaire if os.path.exists(temp_filename): os.remove(temp_filename)