from pydantic import BaseModel, ConfigDict from typing import Optional, List from datetime import datetime class TagBase(BaseModel): name: str class TagCreate(TagBase): pass class TagResponse(TagBase): id: int model_config = ConfigDict(from_attributes=True) class ModelFileBase(BaseModel): filename: str file_type: str = 'stl' part_name: Optional[str] = None is_primary: bool = False file_size: Optional[int] = None class ModelFileResponse(ModelFileBase): id: int file_path: str model_config = ConfigDict(from_attributes=True) class RatingResponse(BaseModel): id: int stars: int created_at: datetime model_config = ConfigDict(from_attributes=True) class CommentResponse(BaseModel): id: int author_name: Optional[str] text: str created_at: datetime model_config = ConfigDict(from_attributes=True) class CollectionBase(BaseModel): name: str description: Optional[str] = None class CollectionCreate(CollectionBase): pass class CollectionResponse(CollectionBase): id: int created_at: datetime model_count: int = 0 model_config = ConfigDict(from_attributes=True) class CollectionDetailResponse(CollectionResponse): models: List['Model3DResponse'] = [] model_config = ConfigDict(from_attributes=True) class Model3DBase(BaseModel): title: str description: Optional[str] = None author: Optional[str] = None license: Optional[str] = None category: Optional[str] = None class Model3DCreate(Model3DBase): tag_names: Optional[List[str]] = [] class Model3DUpdate(BaseModel): title: Optional[str] = None description: Optional[str] = None author: Optional[str] = None license: Optional[str] = None category: Optional[str] = None tag_names: Optional[List[str]] = None class Model3DResponse(Model3DBase): id: int filename: str file_size: Optional[int] file_hash: Optional[str] width: Optional[float] height: Optional[float] depth: Optional[float] faces: Optional[int] created_at: datetime thumbnail_path: Optional[str] download_count: int avg_rating: Optional[float] = None tags: List[TagResponse] = [] files: List[ModelFileResponse] = [] ratings: List[RatingResponse] = [] comments: List[CommentResponse] = [] collections: List[CollectionResponse] = [] model_config = ConfigDict(from_attributes=True)