add test module

This commit is contained in:
2026-08-16 15:39:52 +08:00
parent d0310620fc
commit 6e4d93cea6
46 changed files with 3880 additions and 206 deletions

View File

@@ -1,4 +1,5 @@
from typing import List, Optional
from datetime import datetime
from typing import Dict, List, Literal, Optional
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
@@ -10,6 +11,8 @@ class SentenceBoundary(BaseModel):
start_ms: int = Field(ge=0)
end_ms: int = Field(gt=0)
text: Optional[str] = None
language: Optional[str] = None
reference_speech_duration_ms: Optional[int] = Field(default=None, gt=0)
@model_validator(mode="after")
def validate_range(self):
@@ -46,3 +49,79 @@ class SentenceBoundaryDocument(BaseModel):
raise ValueError("sentence end_ms cannot exceed duration_ms")
previous_end = sentence.end_ms
return self
VideoStatus = Literal["uploaded", "processing", "ready", "failed"]
class VideoSummary(BaseModel):
model_config = ConfigDict(extra="forbid")
video_hash: str
title: str
filename: str
content_type: str
size_bytes: int = Field(ge=0)
duration_ms: Optional[int] = Field(default=None, gt=0)
language: Optional[str] = None
status: VideoStatus
error_message: Optional[str] = None
sentence_count: int = Field(ge=0)
stream_url: str
created_at: datetime
updated_at: datetime
class VideoListResponse(BaseModel):
videos: List[VideoSummary]
class VideoUploadResponse(BaseModel):
video_hash: str
status: VideoStatus
detail_url: str
class VideoDetailResponse(BaseModel):
video: VideoSummary
boundaries: Optional[SentenceBoundaryDocument] = None
class SentenceTextUpdate(BaseModel):
text: str = Field(min_length=1, max_length=4000)
language: Optional[str] = Field(default=None, max_length=32)
class TextSubstitution(BaseModel):
expected: str
actual: str
class AssessmentResult(BaseModel):
model_config = ConfigDict(extra="forbid")
attempt_id: str
scoring_version: str
overall_score: float = Field(ge=0, le=100)
passed: bool
pass_score: float = Field(ge=0, le=100)
content_score: float = Field(ge=0, le=100)
completeness_score: float = Field(ge=0, le=100)
fluency_score: float = Field(ge=0, le=100)
pronunciation_score: Optional[float] = Field(default=None, ge=0, le=100)
prosody_score: Optional[float] = Field(default=None, ge=0, le=100)
duration_score: float = Field(ge=0, le=100)
pause_score: float = Field(ge=0, le=100)
speech_rate_score: float = Field(ge=0, le=100)
reference_text: str
recognized_text: str
reference_duration_ms: int = Field(gt=0)
reference_speech_duration_ms: int = Field(gt=0)
student_recording_duration_ms: int = Field(gt=0)
student_speech_duration_ms: int = Field(gt=0)
duration_ratio: float = Field(gt=0)
missing_tokens: List[str]
extra_tokens: List[str]
substitutions: List[TextSubstitution]
feedback: str
details: Dict[str, str] = Field(default_factory=dict)