add test module
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user