Skip to content

Usage

Downmixer is a Python library providing the core framework for building music service tools. It's designed to be modular and composable — you implement the providers and processing logic your application needs, using Downmixer's building blocks.

There is no CLI. You write Python scripts or applications that use Downmixer's types, protocols, and matching engine.

Installation

pip install downmixer

Core Concepts

Providers

Providers communicate with music services and implement capability protocols:

Protocol Description
SupportsMetadata Search and fetch song/album/artist/playlist metadata
SupportsAudioDownload Download audio files
SupportsLibrary Access user's saved library
SupportsLyrics Fetch song lyrics

Implement your own providers by subclassing BaseProvider and implementing the protocols relevant to your service.

Library Types

Standardized data structures in downmixer.types.library:

  • Song, Album, Artist, Playlist, User — music metadata
  • SearchResult — wraps results with provider info, delegates attribute access

Matching

When comparing tracks across providers, use the matching engine to score how well two songs correspond. See the matching documentation for details on how match quality is scored.

Building Custom Workflows

Implement a Provider

from downmixer.providers import BaseProvider
from downmixer.providers.connections import Connection
from downmixer.providers.protocols import SupportsMetadata
from downmixer.types.library import Song, SearchResult


class MyConnection(Connection):
    _default_options = {}

    def initialize(self) -> bool:
        # set up self.client here
        return True

    def check_valid_url(self, url: str, type_filter=None) -> bool:
        return url.startswith("https://myservice.com/")

    def get_resource_type(self, value: str):
        return None


class MyProvider(BaseProvider, SupportsMetadata):
    _name = "myservice"
    _pretty_name = "My Service"

    async def search(self, query: Song, **kwargs) -> list[SearchResult]:
        # implement search logic
        ...

    async def fetch_song(self, url: str, **kwargs) -> Song:
        # implement fetch logic
        ...

Check Protocol Support

Use issubclass() to check what a provider class supports:

from downmixer.providers.protocols import SupportsLyrics, SupportsAudioDownload

if issubclass(type(provider), SupportsLyrics):
    lyrics = provider.fetch_lyrics(song)

if issubclass(type(provider), SupportsAudioDownload):
    if provider.is_downloadable(song):
        local_file = provider.fetch_audio(song, temp_folder)

Filter by Match Quality

from downmixer.matching import match, MatchQuality

result = match(song_a, song_b)
if result.quality in (MatchQuality.PERFECT, MatchQuality.GREAT):
    # high confidence match
    pass

Reference