yasmine hemmati
Initial deployment: LumaSpeech Backend API with GPU support
d646f8a
Raw
History Blame Contribute Delete
3.34 kB
"""
Practice session and analysis models
"""
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Float, JSON, Text, Boolean
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from config.database import Base
class PracticeSession(Base):
__tablename__ = "practice_sessions"
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey("students.id"), nullable=False)
assignment_id = Column(Integer, ForeignKey("assignments.id"), nullable=True)
# Session info
practice_type = Column(String, nullable=False) # conversation, reading, articulation
technique = Column(String, nullable=False) # normal, prolonged_speech, easy_onset
duration_seconds = Column(Float)
# Content
prompt_text = Column(Text) # What they were supposed to say/read
transcribed_text = Column(Text) # What they actually said
audio_file_path = Column(JSON) # Array of audio file paths (for multi-turn sessions) or single path
# Format: ["sessionID_date_studentID_therapistID_turn1.wav", "sessionID_date_studentID_therapistID_turn2.wav", ...]
# For reading practice: single string or array with one element
# Quick metrics
total_words = Column(Integer)
words_per_minute = Column(Float)
# Status
is_completed = Column(Boolean, default=False)
completed_at = Column(DateTime(timezone=True))
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
student = relationship("Student", back_populates="sessions")
assignment = relationship("Assignment", back_populates="sessions")
analysis = relationship("SessionAnalysis", back_populates="session", uselist=False)
def __repr__(self):
return f"<PracticeSession {self.id} - {self.practice_type}>"
class SessionAnalysis(Base):
__tablename__ = "session_analyses"
id = Column(Integer, primary_key=True)
session_id = Column(Integer, ForeignKey("practice_sessions.id"), unique=True, nullable=False)
# Analysis results (stored as JSON for flexibility)
stutter_analysis = Column(JSON) # Detailed stutter types, counts, locations
fluency_analysis = Column(JSON) # Prolongation %, consistency scores
rushed_speech_analysis = Column(JSON) # Burst patterns, pause analysis
articulation_analysis = Column(JSON) # Accuracy scores per sound
# Summary metrics
total_stutters = Column(Integer, default=0)
stutter_frequency_percent = Column(Float, default=0.0)
fluency_score = Column(Float) # 0-100
rushed_speech_severity = Column(String) # minimal, mild, moderate, severe
articulation_accuracy = Column(Float) # 0-100
# Affected phonemes/patterns
struggled_phonemes = Column(JSON) # List of problem sounds
stutter_patterns = Column(JSON) # Common patterns identified
# Feedback
patient_feedback = Column(Text) # Generated patient-friendly feedback
therapist_notes = Column(Text) # Detailed clinical notes
# Timestamps
analyzed_at = Column(DateTime(timezone=True), server_default=func.now())
# Relationships
session = relationship("PracticeSession", back_populates="analysis")
def __repr__(self):
return f"<SessionAnalysis for session {self.session_id}>"