Add voice

This commit is contained in:
2026-04-05 10:13:28 +02:00
parent 1ca69e94c1
commit 55bd8a4e6b
3 changed files with 36 additions and 4 deletions

View File

@@ -1,11 +1,18 @@
from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI, HTTPException
from fastapi import Depends, FastAPI, File, HTTPException, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from .database import Base, engine, get_db
from . import models, schemas
from .curriculum import QUESTIONS
from .services import build_llm_reply, ensure_student_mastery, evaluate_answer, pick_next_skill, seed_skills
from .services import (
build_llm_reply,
ensure_student_mastery,
evaluate_answer,
pick_next_skill,
seed_skills,
transcribe_audio,
)
@asynccontextmanager
@@ -21,8 +28,6 @@ async def lifespan(app: FastAPI):
app = FastAPI(title="Professeur Virtuel API", version="0.1.0", lifespan=lifespan)
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=[
@@ -87,6 +92,23 @@ def chat(payload: schemas.ChatRequest, db: Session = Depends(get_db)):
return schemas.ChatResponse(reply=reply)
@app.post("/transcribe")
async def transcribe(file: UploadFile = File(...)):
if not file.filename:
raise HTTPException(status_code=400, detail="Fichier audio manquant")
audio_bytes = await file.read()
if not audio_bytes:
raise HTTPException(status_code=400, detail="Fichier audio vide")
try:
text = transcribe_audio(file.filename, audio_bytes, file.content_type)
except Exception as exc:
raise HTTPException(status_code=502, detail=f"Erreur de transcription: {exc}") from exc
return {"text": text}
@app.get("/progress/{student_id}", response_model=schemas.ProgressResponse)
def get_progress(student_id: int, db: Session = Depends(get_db)):
student = db.query(models.Student).filter_by(id=student_id).first()

View File

@@ -88,6 +88,15 @@ def build_llm_reply(db: Session, student_id: int, user_message: str) -> str:
return response.output_text.strip()
def transcribe_audio(filename: str, audio_bytes: bytes, content_type: str | None = None) -> str:
file_payload = (filename, audio_bytes, content_type or "application/octet-stream")
transcript = client.audio.transcriptions.create(
model="gpt-4o-mini-transcribe",
file=file_payload,
)
return (getattr(transcript, "text", "") or "").strip()
def pick_next_skill(db: Session, student_id: int) -> models.Skill:
weakest = (
db.query(models.StudentSkillMastery)

View File

@@ -4,6 +4,7 @@ sqlalchemy==2.0.40
psycopg2-binary==2.9.10
pydantic==2.10.6
python-dotenv==1.0.1
python-multipart==0.0.20
openai==1.72.0
redis==5.2.1
alembic==1.15.2