"""Music schemas.""" from datetime import datetime from typing import Optional, List from uuid import UUID from pydantic import BaseModel, Field, ConfigDict class ArtistBase(BaseModel): """Base artist schema.""" name: str image_url: Optional[str] = None bio: Optional[str] = None genres: List[str] = Field(default_factory=list) popularity: int = 0 class ArtistResponse(ArtistBase): """Schema for artist response.""" model_config = ConfigDict(from_attributes=True) id: UUID spotify_id: Optional[str] = None youtube_id: Optional[str] = None created_at: datetime updated_at: datetime class AlbumBase(BaseModel): """Base album schema.""" title: str release_date: Optional[datetime] = None image_url: Optional[str] = None total_tracks: int = 0 genre: Optional[str] = None class AlbumResponse(AlbumBase): """Schema for album response.""" model_config = ConfigDict(from_attributes=True) id: UUID artist_id: Optional[UUID] = None spotify_id: Optional[str] = None youtube_playlist_id: Optional[str] = None created_at: datetime updated_at: datetime class TrackBase(BaseModel): """Base track schema.""" title: str duration: Optional[int] = Field(None, description="Duration in seconds") track_number: Optional[int] = None disc_number: int = 1 image_url: Optional[str] = None genre: Optional[str] = None mood: Optional[str] = None class TrackResponse(TrackBase): """Schema for track response.""" model_config = ConfigDict(from_attributes=True) id: UUID artist_id: Optional[UUID] = None album_id: Optional[UUID] = None artist: Optional[ArtistResponse] = None album: Optional[AlbumResponse] = None audio_url: Optional[str] = None audio_quality: Optional[str] = None play_count: int = 0 spotify_id: Optional[str] = None youtube_id: Optional[str] = None soundcloud_id: Optional[str] = None created_at: datetime updated_at: datetime class TrackSearchResult(BaseModel): """Schema for track search result.""" id: UUID title: str duration: Optional[int] = None image_url: Optional[str] = None artist: Optional[str] = None album: Optional[str] = None audio_url: Optional[str] = None class SearchRequest(BaseModel): """Schema for search request.""" query: str = Field(..., min_length=1, max_length=100) type: Optional[str] = Field("track", pattern="^(track|artist|album|all)$") limit: int = Field(20, ge=1, le=100) offset: int = Field(0, ge=0) class SearchResponse(BaseModel): """Schema for search response.""" tracks: List[TrackSearchResult] = Field(default_factory=list) artists: List[ArtistResponse] = Field(default_factory=list) albums: List[AlbumResponse] = Field(default_factory=list) total: int query: str class StreamUrlResponse(BaseModel): """Schema for stream URL response.""" url: str format: str = "audio/mpeg" duration: Optional[int] = None class YouTubeSearchResult(BaseModel): """Schema for YouTube search result.""" youtube_id: str title: str artist: Optional[str] = None duration: Optional[int] = None thumbnail: Optional[str] = None