15 KiB
AGENTS.md - AI/LLM Context Guide
This document provides context for AI agents and LLMs to understand and work with the YouMusic project effectively.
Project Overview
YouMusic is a modern, full-stack web music player with download capabilities. It allows users to search, download, and play music from YouTube and Bilibili, manage playlists, and share music links.
Technology Stack
- Backend: Python 3.13, FastAPI, SQLAlchemy (async), yt-dlp, mutagen, uv (package manager)
- Frontend: React 18, TypeScript, Vite, TanStack Query, shadcn/ui, Tailwind CSS
- Database: SQLite with aiosqlite (async driver)
- Deployment: Docker Compose, or local development scripts
Project Type
- Full-stack web application
- Single-page application (SPA)
- REST API backend
- Mobile-first responsive design
- Single-user, no authentication
Architecture
Backend (FastAPI)
backend/
├── main.py # Entry point, FastAPI app initialization
└── app/
├── api/ # REST API endpoints
│ ├── music.py # Music CRUD operations
│ ├── playlist.py # Playlist management
│ ├── download.py # Download from YouTube/Bilibili
│ └── search.py # Search online sources
├── core/
│ └── config.py # Settings using Pydantic
├── db/
│ └── session.py # SQLAlchemy async setup
├── models/
│ └── models.py # Music, Playlist, associations
├── schemas/
│ └── schemas.py # Pydantic request/response models
└── services/
├── downloader.py # yt-dlp music download logic
└── search.py # YouTube/Bilibili search
Key Backend Concepts:
- Async/await throughout for performance
- Background tasks for downloads
- RESTful API design
- Auto-generated OpenAPI/Swagger docs at
/docs - CORS enabled for frontend communication
Frontend (React)
frontend/src/
├── main.tsx # React app entry, providers
├── App.tsx # Main app, routing, player state
├── components/
│ ├── ui/ # shadcn/ui components
│ ├── player/ # Music player
│ ├── search/ # Search interface
│ └── playlist/ # Playlist management
├── api/
│ └── client.ts # Axios API client
├── lib/
│ └── utils.ts # Helper functions
└── types/
└── index.ts # TypeScript interfaces
Key Frontend Concepts:
- Component-based architecture
- TanStack Query for server state
- React Router for navigation
- shadcn/ui for accessible components
- Mobile-first responsive design
- Hot module replacement (HMR) in dev
Database Schema
⚠️ IMPORTANT: Database Migrations
This project uses Alembic for database migrations. When modifying database schema:
- Never delete the database in production
- Always create migrations:
cd backend && ./migrate.sh create "description" - Review the generated migration in
alembic/versions/ - Apply with:
./migrate.sh upgrade - See MIGRATIONS.md for complete guide
Migrations run automatically on app startup, so existing deployments will auto-upgrade.
Tables
music
id: Primary keytitle: Song nameartist: Artist/singer name (nullable)album: Album name (nullable)duration: Length in seconds (nullable)file_path: Relative path to audio filefile_size: File size in bytessource_url: Original download URL (nullable)source_type: "youtube", "bilibili", "local", "upload"thumbnail: Image URL (nullable)lyrics: Song lyrics (nullable)created_at,updated_at: Timestamps
playlists
id: Primary keyname: Playlist name (unique)description: Playlist description (nullable)thumbnail: Playlist image (nullable)created_at,updated_at: Timestamps
playlist_music (Many-to-Many)
playlist_id: Foreign key to playlistsmusic_id: Foreign key to musicposition: Order in playlistadded_at: Timestamp
Relationships
- One playlist has many music items
- One music item can be in many playlists
API Endpoints
Music API (/api/music/)
GET /- List all musicGET /search?q={query}- Search local libraryGET /{id}- Get music by IDGET /artist/{name}- Get all music by artistPUT /{id}- Update metadataDELETE /{id}- Delete music and filePOST /upload- Upload music filePOST /scan- Scan directory for new files
Playlist API (/api/playlists/)
GET /- List all playlistsPOST /- Create playlistGET /{id}- Get playlist with songsGET /name/{name}- Get playlist by namePUT /{id}- Update playlistDELETE /{id}- Delete playlistPOST /{id}/music/{music_id}- Add songDELETE /{id}/music/{music_id}- Remove song
Download API (/api/download/)
POST /music- Download single track (background task)POST /playlist- Download entire playlist (background task)GET /status- Download queue status
Search API (/api/search/)
GET /?q={query}&source={all|youtube|bilibili}- Search onlineGET /youtube?q={query}- Search YouTube onlyGET /bilibili?q={query}- Search Bilibili only
Core Features
1. Music Download (from xiaomusic)
The download logic is adapted from xiaomusic using yt-dlp:
# Core download command
yt-dlp --no-playlist -x --audio-format mp3 \
--audio-quality 0 --paths {music_dir} \
-o "{title}.%(ext)s" {url}
Supported sources:
- YouTube videos and playlists
- Bilibili videos
- Any site supported by yt-dlp
2. Music Player
- HTML5 audio element
- Play/pause, skip forward/back
- Volume control with mute
- Progress bar with seeking
- Auto-play next in queue
- Display current track info
3. Search
- Local: SQLAlchemy LIKE queries on title/artist
- Online: yt-dlp JSON dump for YouTube, Bilibili API for Bilibili
- Combined results with thumbnails
- Artist-based filtering
4. Playlists
- Create, read, update, delete
- Add/remove songs
- Play entire playlist
- Maintain song order
5. Music Sharing
- Share via URL:
/?music={id} - Auto-load and play shared music
- Deep linking support
Development Modes
Local Development (Fastest)
./dev-setup.sh # First time
./dev.sh # Daily development
./dev-stop.sh # Stop servers
Ports:
- Frontend: http://localhost:3000 (Vite dev server)
- Backend: http://localhost:8000 (uvicorn with reload)
Features:
- Hot reload for both frontend and backend
- Instant file changes
- Native performance
- Logs in
logs/directory
Docker Deployment
docker-compose up -d
Ports:
- Combined app: http://localhost:8000 (frontend served by backend)
File Conventions
Backend
- Naming:
snake_casefor files, functions, variables - Async: All I/O operations use
async/await - Type hints: All functions have type hints
- Imports: Absolute imports from
app.
Frontend
- Naming:
PascalCasefor components,camelCasefor functions/variables - Files:
.tsxfor components,.tsfor utilities - Exports: Named exports preferred
- Hooks: Custom hooks in
hooks/directory
API Communication
- All endpoints return JSON
- Error responses follow FastAPI conventions
- Request/response validated by Pydantic schemas
- CORS enabled for cross-origin requests
Common Tasks for AI Agents
Adding a New API Endpoint
-
Create endpoint in
backend/app/api/@router.get("/new-endpoint") async def new_endpoint(db: AsyncSession = Depends(get_db)): # Implementation pass -
Add to router in
backend/main.pyapp.include_router(new_router, prefix="/api/new", tags=["new"]) -
Add API client function in
frontend/src/api/client.tsexport const newApi = { getItems: () => api.get('/new-endpoint'), } -
Use in component with TanStack Query
const { data } = useQuery({ queryKey: ['new-items'], queryFn: async () => { const response = await newApi.getItems() return response.data } })
Adding a New UI Component
-
Create component in
frontend/src/components/export default function NewComponent({ prop }: Props) { return <div>...</div> } -
Use shadcn/ui components from
@/components/ui/ -
Add to routing in
App.tsxif needed -
Use Tailwind for styling
Modifying Database Schema
IMPORTANT: We use Alembic for database migrations. Never delete the database in production!
-
Update model in
backend/app/models/models.pyclass Music(Base): # ... existing fields ... new_field: Mapped[Optional[str]] = mapped_column(String, nullable=True) -
Create migration
cd backend ./migrate.sh create "Add new_field to music table" -
Review generated migration in
backend/alembic/versions/*.py- Check auto-generated SQL is correct
- Edit if needed (e.g., for renaming columns, data migrations)
-
Apply migration
./migrate.sh upgrade -
Update schema in
backend/app/schemas/schemas.pyif needed
Notes:
- Migrations run automatically on app startup
- Never edit applied migrations - create new ones
- Use
./migrate.sh downgradeto rollback if needed - See MIGRATIONS.md for complete guide
Adding Download Source
- Check yt-dlp support (most sites already supported)
- Add search function in
backend/app/services/search.py - Update search endpoint in
backend/app/api/search.py - Add UI in
frontend/src/components/search/SearchPage.tsx
Environment Variables
Backend (.env)
DATABASE_URL=sqlite+aiosqlite:///./data/youmusic.db
MUSIC_DIR=./data/music
UPLOAD_DIR=./data/uploads
TEMP_DIR=./data/temp
FFMPEG_LOCATION=ffmpeg
PROXY=http://proxy:port # Optional
Frontend (.env)
VITE_API_URL=http://localhost:8000
Testing
Backend
cd backend
pytest
Frontend
cd frontend
npm test
API Testing
- Visit http://localhost:8000/docs for interactive testing
- Use curl, Postman, or Thunder Client
Dependencies
Key Backend Packages
fastapi- Web frameworkuvicorn- ASGI serversqlalchemy- ORMaiosqlite- Async SQLite driveralembic- Database migrationsyt-dlp- Universal downloadermutagen- Audio metadatapydantic- Data validation
Key Frontend Packages
react- UI library@tanstack/react-query- Data fetchingreact-router-dom- Routingaxios- HTTP clienttailwindcss- Stylinglucide-react- Icons
Code Patterns
Backend Async Pattern
async def get_items(db: AsyncSession = Depends(get_db)):
result = await db.execute(select(Model))
items = result.scalars().all()
return items
Frontend Query Pattern
const { data, isLoading } = useQuery({
queryKey: ['items'],
queryFn: async () => {
const response = await api.get('/items')
return response.data
}
})
Error Handling
# Backend
raise HTTPException(status_code=404, detail="Not found")
# Frontend
try {
await api.call()
toast.success('Success!')
} catch (error) {
toast.error('Failed!')
}
Performance Considerations
Backend
- Use async for all I/O operations
- Background tasks for long-running downloads
- Database indexes on frequently queried fields
- Limit query results with pagination
Frontend
- Lazy load components
- Use TanStack Query caching
- Debounce search inputs
- Optimize images
Security
Backend
- Input validation via Pydantic
- SQL injection protection via SQLAlchemy
- Path traversal protection in file operations
- CORS configuration
Frontend
- XSS protection via React
- No eval() or dangerouslySetInnerHTML
- Sanitize user inputs
- Secure URL parsing
Debugging
Backend
- Check logs:
tail -f logs/backend.log - Use print statements (shown in logs)
- FastAPI auto-reloads on code changes
- Test in browser: http://localhost:8000/docs
Frontend
- Check logs:
tail -f logs/frontend.log - Browser console for errors
- React DevTools for component inspection
- Network tab for API calls
Common Errors
"Module not found"
- Backend: Activate .venv,
uv pip install -r requirements.txt - Frontend:
npm install
"Port already in use"
lsof -ti:8000 | xargs kill -9 # Backend
lsof -ti:3000 | xargs kill -9 # Frontend
"FFmpeg not found"
brew install ffmpeg # macOS
sudo apt-get install ffmpeg # Ubuntu
"Database locked"
- Only one process can write at a time
- Restart backend:
./dev-stop.sh && ./dev.sh
AI Agent Guidelines
When Adding Features
- Check if dependencies are already installed
- Follow existing code patterns
- Update both backend and frontend if needed
- Add type hints/types
- Test the feature
- Update relevant documentation
When Debugging
- Check logs first
- Verify dependencies are installed
- Ensure servers are running
- Test API endpoints separately
- Check browser console
When Refactoring
- Don't break existing features
- Maintain async patterns
- Keep type safety
- Update tests if they exist
- Follow project conventions
Code Style
- Backend: Follow PEP 8, use async/await
- Frontend: Use TypeScript, functional components
- Both: Clear variable names, comments for complex logic
Project Goals
- Simplicity - Easy to understand and modify
- Performance - Fast response times, efficient queries
- Maintainability - Clear structure, good documentation
- Mobile-First - Responsive design, touch-friendly
- Single-User - No authentication complexity
Related Projects
- xiaomusic: Inspired download logic and yt-dlp usage
- spotube: UI/UX design inspiration
- shadcn/ui: Component library
- yt-dlp: Download engine
Resources
- FastAPI docs: https://fastapi.tiangolo.com
- React docs: https://react.dev
- yt-dlp: https://github.com/yt-dlp/yt-dlp
- shadcn/ui: https://ui.shadcn.com
- TanStack Query: https://tanstack.com/query
Version Information
- Current Version: 1.0.0
- Python: 3.13
- uv: Latest
- Node.js: 18+
- React: 18.3.1
- FastAPI: 0.115.0
License
MIT License - Free to use and modify
For AI Agents: This project is well-structured, fully typed, and follows modern best practices. Feel free to suggest improvements, add features, or refactor code while maintaining the existing patterns and architecture.
No need to create summary doc after made changes