Add voice
This commit is contained in:
@@ -1,11 +1,18 @@
|
|||||||
from contextlib import asynccontextmanager
|
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 fastapi.middleware.cors import CORSMiddleware
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from .database import Base, engine, get_db
|
from .database import Base, engine, get_db
|
||||||
from . import models, schemas
|
from . import models, schemas
|
||||||
from .curriculum import QUESTIONS
|
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
|
@asynccontextmanager
|
||||||
@@ -21,8 +28,6 @@ async def lifespan(app: FastAPI):
|
|||||||
|
|
||||||
app = FastAPI(title="Professeur Virtuel API", version="0.1.0", lifespan=lifespan)
|
app = FastAPI(title="Professeur Virtuel API", version="0.1.0", lifespan=lifespan)
|
||||||
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
|
||||||
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=[
|
allow_origins=[
|
||||||
@@ -87,6 +92,23 @@ def chat(payload: schemas.ChatRequest, db: Session = Depends(get_db)):
|
|||||||
return schemas.ChatResponse(reply=reply)
|
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)
|
@app.get("/progress/{student_id}", response_model=schemas.ProgressResponse)
|
||||||
def get_progress(student_id: int, db: Session = Depends(get_db)):
|
def get_progress(student_id: int, db: Session = Depends(get_db)):
|
||||||
student = db.query(models.Student).filter_by(id=student_id).first()
|
student = db.query(models.Student).filter_by(id=student_id).first()
|
||||||
|
|||||||
@@ -88,6 +88,15 @@ def build_llm_reply(db: Session, student_id: int, user_message: str) -> str:
|
|||||||
return response.output_text.strip()
|
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:
|
def pick_next_skill(db: Session, student_id: int) -> models.Skill:
|
||||||
weakest = (
|
weakest = (
|
||||||
db.query(models.StudentSkillMastery)
|
db.query(models.StudentSkillMastery)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ sqlalchemy==2.0.40
|
|||||||
psycopg2-binary==2.9.10
|
psycopg2-binary==2.9.10
|
||||||
pydantic==2.10.6
|
pydantic==2.10.6
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
|
python-multipart==0.0.20
|
||||||
openai==1.72.0
|
openai==1.72.0
|
||||||
redis==5.2.1
|
redis==5.2.1
|
||||||
alembic==1.15.2
|
alembic==1.15.2
|
||||||
|
|||||||
Reference in New Issue
Block a user