From 037e59fe8f528a6ccded8848303c07ee45e1a261 Mon Sep 17 00:00:00 2001 From: Sebastian Mohr Date: Tue, 26 Aug 2025 12:15:25 +0200 Subject: [PATCH] Created autotagger file and enhanced the docs significantly. --- docs/dev/plugins/autotagger.rst | 103 ++++++++++++++++++++++++++++++++ docs/dev/plugins/index.rst | 1 + docs/dev/plugins/other.rst | 23 ------- 3 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 docs/dev/plugins/autotagger.rst diff --git a/docs/dev/plugins/autotagger.rst b/docs/dev/plugins/autotagger.rst new file mode 100644 index 000000000..2d59ecdcf --- /dev/null +++ b/docs/dev/plugins/autotagger.rst @@ -0,0 +1,103 @@ +Extending the Autotagger +======================== + +.. currentmodule:: beets.metadata_plugins + +Beets supports **metadata source plugins**, which allow it to fetch and match +metadata from external services (such as Spotify, Discogs, or Deezer). This +guide explains how to build your own metadata source plugin by extending the +:py:class:`MetadataSourcePlugin`. + +These plugins integrate directly with the autotagger, providing candidate +metadata during lookups. To implement one, you must subclass +:py:class:`MetadataSourcePlugin` and implement its abstract methods. + +Overview +-------- + +Creating a metadata source plugin is very similar to writing a standard plugin +(see :ref:`basic-plugin-setup`). The main difference is that your plugin must: + +1. Subclass :py:class:`MetadataSourcePlugin`. +2. Implement all required abstract methods. + +Here`s a minimal example: + +.. code-block:: python + + # beetsplug/myawesomeplugin.py + from typing import Sequence + from beets.autotag.hooks import Item + from beets.metadata_plugin import MetadataSourcePlugin + + + class MyAwesomePlugin(MetadataSourcePlugin): + + def candidates( + self, + items: Sequence[Item], + artist: str, + album: str, + va_likely: bool, + ): ... + + def item_candidates(self, item: Item, artist: str, title: str): ... + + def track_for_id(self, track_id: str): ... + + def album_for_id(self, album_id: str): ... + +How Metadata Lookup Works +------------------------- + +When beets runs the autotagger, it queries **all enabled metadata source +plugins** for potential matches: + +- For **albums**, it calls :py:meth:`~MetadataSourcePlugin.candidates`. +- For **individual items**, it calls + :py:meth:`~MetadataSourcePlugin.item_candidates`. + +The results are combined and scored. By default, candidate ranking is handled +automatically by the beets core, but you can customize weighting by overriding: + +- :py:meth:`~MetadataSourcePlugin.album_distance` +- :py:meth:`~MetadataSourcePlugin.track_distance` + +This is optional, if not overridden, both methods return a constant distance of +`0.5`. + +Implementing ID-based Lookups +----------------------------- + +Your plugin must also define: + +- :py:meth:`~MetadataSourcePlugin.album_for_id` — fetch album metadata by ID. +- :py:meth:`~MetadataSourcePlugin.track_for_id` — fetch track metadata by ID. + +These methods should return `None` if your source doesn`t support ID lookups. +IDs are expected to be strings. If your source uses specific formats, consider +contributing an extractor regex to the core module: +:py:mod:`beets.util.id_extractors`. + +Best Practices +-------------- + +Beets already ships with several metadata source plugins. Studying these +implementations can help you follow conventions and avoid pitfalls. Good +starting points include: + +- `spotify` +- `deezer` +- `discogs` + +Migration Guidance +------------------ + +Older metadata plugins that extend :py:class:`beets.plugins.BeetsPlugin` should +be migrated to :py:class:`MetadataSourcePlugin`. Legacy support will be removed +in **beets v3.0.0**. + +.. seealso:: + + - :py:mod:`beets.autotag` + - :py:mod:`beets.metadata_plugins` diff --git a/docs/dev/plugins/index.rst b/docs/dev/plugins/index.rst index ff5a03652..1321c61dc 100644 --- a/docs/dev/plugins/index.rst +++ b/docs/dev/plugins/index.rst @@ -99,4 +99,5 @@ resources: commands events + autotagger other diff --git a/docs/dev/plugins/other.rst b/docs/dev/plugins/other.rst index 20441c0e9..164bac13c 100644 --- a/docs/dev/plugins/other.rst +++ b/docs/dev/plugins/other.rst @@ -5,29 +5,6 @@ Further Reading :local: :depth: 2 -Extending the Autotagger ------------------------- - -.. currentmodule:: beets.metadata_plugins - -Plugins can also be used to extend the autotagger functions i.e. the metadata -lookup from external sources. For this your plugin has to extend the -:py:class:`MetadataSourcePlugin` base class and implement all abstract methods. - -On metadata lookup, the autotagger will try to find matching candidates from all -enabled metadata source plugins. To do this, we will call the -:py:meth:`MetadataSourcePlugin.candidates` (or -:py:meth:`MetadataSourcePlugin.item_candidates`) with all available (local) -metadata. The list of retrieved candidates will be ranked by their -:py:meth:`MetadataSourcePlugin.album_distance` (or -:py:meth:`MetadataSourcePlugin.track_distance`) and be presented to the user for -selection (or automatically selected if the threshold is met). - -Please have a look at the ``beets.autotag`` and especially the -``beets.metadata_plugin`` modules for more information. Additionally, for a -comprehensive example, see the ``musicbrainz`` or ``chroma`` plugins, which are -included with beets. - Read Configuration Options --------------------------