study-buddy / app /schemas /annotation.py
GitHub Actions
deploy d092bea3608b7a29952f16357fda39b7a29e399b
2e818da
Raw
History Blame Contribute Delete
1.13 kB
from __future__ import annotations
import time
import uuid
from typing import List, Optional
from pydantic import BaseModel, ConfigDict, Field
class _StrictModel(BaseModel):
model_config = ConfigDict(strict=True, extra="forbid")
class BoundingBox(_StrictModel):
"""Page-normalised bounding box (all coords 0..1, relative to page element)."""
page: int
x: float
y: float
w: float
h: float
class SelectionSnippet(_StrictModel):
page_number: int
text: str
boxes: List[BoundingBox]
char_start: Optional[int] = None
char_end: Optional[int] = None
class StudentAnnotation(_StrictModel):
annotation_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
document_id: str = Field(pattern=r"^[0-9a-f]{64}$")
project_id: str = Field(pattern=r"^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$")
target_snippets: List[SelectionSnippet]
note_text: Optional[str] = None
image_base64: Optional[str] = None # cropped region PNG (pinned figures/tables/formulas)
created_at: float = Field(default_factory=time.time)
updated_at: float = Field(default_factory=time.time)