from typing import List from fastapi import APIRouter, Depends, HTTPException, Query from sqlmodel import Session, select from database import get_session from models import Song, User, Tag, EntityTag from schemas import SongCreate, SongRead, SongReadWithStats, SongUpdate, TagRead from auth import get_current_user router = APIRouter(prefix="/songs", tags=["songs"]) @router.post("/", response_model=SongRead) def create_song(song: SongCreate, session: Session = Depends(get_session), current_user = Depends(get_current_user)): db_song = Song.model_validate(song) session.add(db_song) session.commit() session.refresh(db_song) return db_song @router.get("/", response_model=List[SongRead]) def read_songs(offset: int = 0, limit: int = Query(default=100, le=100), session: Session = Depends(get_session)): songs = session.exec(select(Song).offset(offset).limit(limit)).all() return songs from services.stats import get_song_stats @router.get("/{song_id}", response_model=SongReadWithStats) def read_song(song_id: int, session: Session = Depends(get_session)): song = session.get(Song, song_id) if not song: raise HTTPException(status_code=404, detail="Song not found") stats = get_song_stats(session, song_id) tags = session.exec( select(Tag) .join(EntityTag, Tag.id == EntityTag.tag_id) .where(EntityTag.entity_type == "song") .where(EntityTag.entity_id == song_id) ).all() # Merge song data with stats song_with_stats = SongReadWithStats( **song.model_dump(), **stats ) song_with_stats.tags = tags return song_with_stats @router.patch("/{song_id}", response_model=SongRead) def update_song(song_id: int, song: SongUpdate, session: Session = Depends(get_session), current_user = Depends(get_current_user)): db_song = session.get(Song, song_id) if not db_song: raise HTTPException(status_code=404, detail="Song not found") song_data = song.model_dump(exclude_unset=True) db_song.sqlmodel_update(song_data) session.add(db_song) session.commit() session.refresh(db_song) return db_song