A comprehensive music library management system and command-line application for organizing and maintaining digital music collections
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core database operations for managing music collections including item and album CRUD operations, query execution, and metadata management. The library system provides the foundation for all beets functionality.
The central database interface that manages Items and Albums with an SQLite backend, providing query functionality and transaction management.
class Library:
def __init__(self, path: str, directory: str, path_formats=None, replacements=None):
"""
Initialize a music library.
Parameters:
- path: Path to SQLite database file
- directory: Root directory for music files
- path_formats: List of (query, template) tuples for path formatting
- replacements: List of (regex, replacement) tuples for filename sanitization
"""
def items(self, query: str = None) -> Results:
"""
Query for items (tracks) in the library.
Parameters:
- query: Query string for filtering (optional)
Returns:
Results iterator over matching Item objects
"""
def albums(self, query: str = None) -> Results:
"""
Query for albums in the library.
Parameters:
- query: Query string for filtering (optional)
Returns:
Results iterator over matching Album objects
"""
def add(self, obj: Union[Item, Album]) -> None:
"""
Add an Item or Album to the library database.
Parameters:
- obj: Item or Album object to add
"""
def add_album(self, items: List[Item]) -> Album:
"""
Create an album from a list of items.
Parameters:
- items: List of Item objects to group into an album
Returns:
Album object containing the items
"""
def get_item(self, id: int) -> Item:
"""
Get an item by database ID.
Parameters:
- id: Database ID of the item
Returns:
Item object or None if not found
"""
def get_album(self, id: int) -> Album:
"""
Get an album by database ID.
Parameters:
- id: Database ID of the album
Returns:
Album object or None if not found
"""
def parse_query_string(self, query_string: str, model_cls: Type) -> Query:
"""
Parse a query string into a Query object.
Parameters:
- query_string: String representation of query
- model_cls: Item or Album class
Returns:
Query object for database operations
"""from beets.library import Library
# Create a new library
lib = Library('/home/user/.config/beets/musiclibrary.db', '/home/user/Music')
# Query all items
all_items = lib.items()
print(f"Total tracks: {len(all_items)}")
# Query with filters
recent_items = lib.items('added:2024..')
beatles_albums = lib.albums('artist:Beatles')
# Add items to library
from beets.library import Item
item = Item.from_path('/path/to/song.mp3')
lib.add(item)Represents a single music track/file with comprehensive metadata fields and file operations.
class Item(Model):
# Core metadata fields
title: str
artist: str
album: str
albumartist: str
track: int
disc: int
year: int
month: int
day: int
genre: str
length: float # Duration in seconds
bitrate: int
samplerate: int
channels: int
path: bytes # Filesystem path
mtime: float # Modification time
added: float # Time added to library
@classmethod
def from_path(cls, path: str) -> 'Item':
"""
Create an Item from a file path, reading metadata from file.
Parameters:
- path: Filesystem path to audio file
Returns:
Item object with metadata loaded from file
"""
def add(self, library: Library) -> None:
"""
Add this item to a library database.
Parameters:
- library: Library instance to add to
"""
def store(self) -> None:
"""
Save changes to the database.
"""
def load(self) -> None:
"""
Load metadata from the audio file, updating item fields.
"""
def write(self) -> None:
"""
Write current metadata to the audio file tags.
"""
def move(self, library: Library, operation: str, basedir: str = None) -> None:
"""
Move or copy the item's file according to library path formats.
Parameters:
- library: Library instance for path formatting
- operation: 'move', 'copy', 'link', or 'reflink'
- basedir: Base directory for relative paths (optional)
"""
def remove(self, delete: bool = False, with_album: bool = True) -> None:
"""
Remove item from database and optionally delete file.
Parameters:
- delete: Whether to delete the physical file
- with_album: Whether to remove album if it becomes empty
"""
def formatted(self) -> Dict[str, str]:
"""
Get dictionary of formatted field values for display.
Returns:
Dictionary mapping field names to formatted string values
"""# Core metadata fields with types
title: str # Track title
artist: str # Track artist
album: str # Album name
albumartist: str # Album artist (may differ from track artist)
track: int # Track number within album
disc: int # Disc number for multi-disc albums
year: int # Release year
month: int # Release month (1-12)
day: int # Release day (1-31)
genre: str # Musical genre
length: float # Duration in seconds
bitrate: int # Audio bitrate in kbps
samplerate: int # Sample rate in Hz
channels: int # Number of audio channels
format: str # Audio format (MP3, FLAC, etc.)
path: bytes # Filesystem path to file
mtime: float # File modification time (Unix timestamp)
added: float # Time added to library (Unix timestamp)from beets.library import Item, Library
# Create item from file
item = Item.from_path('/path/to/song.mp3')
print(f"Title: {item.title}, Artist: {item.artist}")
print(f"Duration: {item.length} seconds")
# Modify metadata
item.year = 2024
item.genre = 'Rock'
item.store() # Save to database
# Write metadata to file
item.write()
# Move file according to library path format
lib = Library('/path/to/library.db', '/music')
item.move(lib, 'move') # Move file to organized location
# Access formatted values for display
formatted = item.formatted()
print(f"Formatted: {formatted['artist']} - {formatted['title']}")Represents a collection of tracks as an album with album-level metadata and operations.
class Album(Model):
# Album metadata fields
album: str
albumartist: str
year: int
month: int
day: int
genre: str
albumtotal: int # Total number of tracks
disctotal: int # Total number of discs
artpath: bytes # Path to album art file
def items(self) -> Results:
"""
Get all items (tracks) in this album.
Returns:
Results iterator over Item objects in album
"""
def add(self, library: Library) -> None:
"""
Add this album to a library database.
Parameters:
- library: Library instance to add to
"""
def store(self) -> None:
"""
Save album changes to the database.
"""
def remove(self, delete_items: bool = False) -> None:
"""
Remove album from database.
Parameters:
- delete_items: Whether to also remove all items in the album
"""
def art_destination(self, item: Item) -> str:
"""
Get the destination path for album art based on an item.
Parameters:
- item: Item in the album to base path on
Returns:
Filesystem path for album art file
"""from beets.library import Album, Library
lib = Library('/path/to/library.db', '/music')
# Get albums
beatles_albums = lib.albums('artist:Beatles')
for album in beatles_albums:
print(f"Album: {album.album} ({album.year})")
# Get tracks in album
tracks = album.items()
print(f" {len(tracks)} tracks")
for item in tracks:
print(f" {item.track}. {item.title}")
# Create album from items
items = lib.items('album:"Abbey Road" artist:Beatles')
abbey_road = lib.add_album(list(items))class Model:
"""Base class for database models (Item and Album inherit from this)."""
def store(self) -> None:
"""Save object to database."""
def load(self) -> None:
"""Load object from database."""
def remove(self) -> None:
"""Remove object from database."""
def __getitem__(self, key: str) -> Any:
"""Get field value by name."""
def __setitem__(self, key: str, value: Any) -> None:
"""Set field value by name."""
def get(self, key: str, default: Any = None) -> Any:
"""Get field value with default fallback."""class Results:
"""Iterator over query results with additional functionality."""
def __len__(self) -> int:
"""Get count of results."""
def __iter__(self) -> Iterator:
"""Iterate over result objects."""
def get(self) -> Union[Item, Album, None]:
"""Get single result or None if no matches."""class FileOperationError(Exception):
"""Raised when file operations fail."""
class DBAccessError(Exception):
"""Raised when database access fails."""Common error scenarios:
Install with Tessl CLI
npx tessl i tessl/pypi-beets