Skip to content

typing: type metadata source plugins: discogs, deezer, beatport, spotify chroma, listenbrainz, mbsubmit, spotify - #6938

Open
snejus wants to merge 2 commits into
type-api-export-pluginsfrom
type-metadata-source-plugins
Open

typing: type metadata source plugins: discogs, deezer, beatport, spotify chroma, listenbrainz, mbsubmit, spotify#6938
snejus wants to merge 2 commits into
type-api-export-pluginsfrom
type-metadata-source-plugins

Conversation

@snejus

@snejus snejus commented Aug 18, 2026

Copy link
Copy Markdown
Member

Part of #6924.

  • This change tightens typing across metadata source plugins and shared request/MusicBrainz utilities, so plugin code lines up better with the data it actually consumes.

  • Biggest architecture change is in beetsplug/_utils/musicbrainz.py: common release fields move into BaseRelease, and new RecordingWithReleases plus get_recording_with_releases() make 'recording with releases' an explicit shape instead of loose dict guessing.

  • Plugin code in listenbrainz, chroma, acousticbrainz, beatport, deezer, spotify, discogs, and mbsubmit is then updated to use clearer return types, typed collections, and safer access patterns for optional API data.

  • High-level impact: less ambiguity at plugin boundaries, better editor/type-checker help, and fewer runtime mistakes from assuming fields exist when remote APIs may omit them.

  • There is also a small cleanup in mbsubmit: output formatting now goes through format() with a cached config value, which removes a cross-plugin helper dependency and keeps the command simpler.

Copilot AI lite review requested due to automatic review settings August 18, 2026 09:23
@snejus
snejus requested a review from a team as a code owner August 18, 2026 09:23
@github-actions github-actions Bot added beatport beatport plugin chroma chroma plugin deezer deezer plugin discogs discogs plugin listenbrainz listenbrainz plugin mbsubmit mbsubmit plugin spotify spotify plugin labels Aug 18, 2026
@github-actions

Copy link
Copy Markdown

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.83193% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.99%. Comparing base (87da1ca) to head (38f9195).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
beetsplug/listenbrainz.py 61.53% 8 Missing and 2 partials ⚠️
beetsplug/deezer.py 27.27% 8 Missing ⚠️
beetsplug/chroma.py 84.61% 4 Missing ⚠️
beetsplug/beatport.py 80.00% 1 Missing ⚠️
beetsplug/mbsubmit.py 90.00% 1 Missing ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##           type-api-export-plugins    #6938      +/-   ##
===========================================================
- Coverage                    76.01%   75.99%   -0.02%     
===========================================================
  Files                          164      164              
  Lines                        21577    21585       +8     
  Branches                      3341     3342       +1     
===========================================================
+ Hits                         16401    16404       +3     
- Misses                        4381     4387       +6     
+ Partials                       795      794       -1     
Files with missing lines Coverage Δ
beetsplug/_utils/musicbrainz.py 96.82% <100.00%> (-0.53%) ⬇️
beetsplug/_utils/requests.py 96.66% <100.00%> (ø)
beetsplug/acousticbrainz.py 40.81% <100.00%> (ø)
beetsplug/discogs/__init__.py 69.48% <100.00%> (ø)
beetsplug/spotify.py 63.75% <100.00%> (ø)
beetsplug/beatport.py 44.11% <80.00%> (ø)
beetsplug/mbsubmit.py 56.81% <90.00%> (+3.15%) ⬆️
beetsplug/chroma.py 47.38% <84.61%> (-0.41%) ⬇️
beetsplug/deezer.py 26.17% <27.27%> (-0.18%) ⬇️
beetsplug/listenbrainz.py 59.65% <61.53%> (-1.12%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

grug see PR try make typing tighter for many metadata plugins and shared request/MusicBrainz helpers, so plugin code match real API shapes and type checker help more.

Changes:

  • Add/adjust return + param types across multiple metadata source plugins.
  • Reshape MusicBrainz typing: split Release fields into BaseRelease, add RecordingWithReleases, add get_recording_with_releases().
  • Small mbsubmit cleanup: print via format() with cached format string, drop cross-plugin helper call.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
beetsplug/spotify.py Add richer type hints for plugin lifecycle + matching helpers.
beetsplug/mbsubmit.py Replace print_data with format() output; add cached format property and typing.
beetsplug/listenbrainz.py Type API helpers and switch recording lookup to new “with releases” shape.
beetsplug/discogs/init.py Add typing for importer session hook param.
beetsplug/deezer.py Type commands/update flow; make rank fetch more defensive.
beetsplug/chroma.py Add typing around Acoustid path + release sorting + helpers.
beetsplug/beatport.py Tighten typing on client/plugin helpers.
beetsplug/acousticbrainz.py Tighten typing for request/mapping pipeline and CLI option parsing.
beetsplug/_utils/requests.py Add return annotations for HTTP session helpers/overrides.
beetsplug/_utils/musicbrainz.py Introduce new typed shapes and new recording lookup helper.
Suppressed comments (2)

beetsplug/chroma.py:143

  • grug think .as_str() here make original_year always truthy ("no" still true). this break config match.preferred.original_year: no. should read bool value.
    original_year = config["match"]["preferred"]["original_year"].as_str()

beetsplug/listenbrainz.py:392

  • grug see .get("track") can return None, then loop crash. also identifier can be missing/None, then .split() crash. make safe default list and skip bad entries.
        for track in playlist.get("playlist", {}).get("track"):
            identifier = track.get("identifier")
            if isinstance(identifier, list):
                identifier = identifier[0]


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread beetsplug/chroma.py
Comment thread beetsplug/deezer.py
Comment thread beetsplug/_utils/musicbrainz.py
Comment thread beetsplug/beatport.py
Comment thread beetsplug/spotify.py Outdated
@snejus
snejus force-pushed the type-metadata-source-plugins branch from 5324a42 to ea70c51 Compare August 18, 2026 09:42
@snejus
snejus force-pushed the type-api-export-plugins branch from 8311344 to ca026db Compare August 18, 2026 09:57
@snejus
snejus force-pushed the type-metadata-source-plugins branch from ea70c51 to f8349ad Compare August 18, 2026 09:57
@snejus
snejus force-pushed the type-api-export-plugins branch from ca026db to c764422 Compare August 19, 2026 01:41
@snejus
snejus force-pushed the type-metadata-source-plugins branch from f8349ad to 2a9a56d Compare August 19, 2026 01:41
@snejus
snejus force-pushed the type-api-export-plugins branch from c764422 to 48d67c4 Compare August 19, 2026 01:58
@snejus
snejus requested a review from JOJ0 as a code owner August 19, 2026 01:58
@snejus
snejus force-pushed the type-metadata-source-plugins branch 2 times, most recently from 0e0f5c2 to 1481471 Compare August 19, 2026 02:15
@snejus
snejus requested a lite review from Copilot August 19, 2026 02:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

Suppressed comments (3)

beetsplug/deezer.py:276

  • grug see walrus precedence bug: (rank := track.get("rank") is not None) set rank to bool, so log/int(rank) become 0/1, not Deezer rank value. need bind get() result, then check is not None.
                if track and (rank := track.get("rank") is not None):
                    self._log.debug(
                        "Deezer track: {} has {} rank", deezer_track_id, rank
                    )
                    item.deezer_track_rank = int(rank)

beetsplug/listenbrainz.py:395

  • grug see .get("track") can return None, then for loop crash. also identifier can be None (or empty list) and .split() crash. better default empty list and skip entries with bad identifier.
        tracks = []
        for track in playlist.get("playlist", {}).get("track"):
            identifier = track.get("identifier")
            if isinstance(identifier, list):
                identifier = identifier[0]

beetsplug/spotify.py:611

  • grug see _match_library_tracks() always calls _search_api("track", ...) and appends track objects, so return type should be list[SearchResponseTracks] | None (not album union). tighter type make later code safer.
    def _match_library_tracks(
        self, library: Library, keywords: list[str]
    ) -> list[SearchResponseAlbums | SearchResponseTracks] | None:

@snejus
snejus force-pushed the type-api-export-plugins branch from 48d67c4 to b9de1ce Compare August 19, 2026 02:24
@snejus
snejus force-pushed the type-metadata-source-plugins branch from 1481471 to 211f4c3 Compare August 19, 2026 02:24
@snejus
snejus force-pushed the type-api-export-plugins branch from b9de1ce to 485ae8d Compare August 19, 2026 04:00
@snejus
snejus force-pushed the type-metadata-source-plugins branch from 211f4c3 to 8aa82f1 Compare August 19, 2026 04:00
@snejus
snejus force-pushed the type-api-export-plugins branch from 485ae8d to 01233c7 Compare August 19, 2026 10:00
@snejus
snejus force-pushed the type-metadata-source-plugins branch from 8aa82f1 to 20145a4 Compare August 19, 2026 10:00
@snejus
snejus force-pushed the type-api-export-plugins branch from 01233c7 to 7494176 Compare August 19, 2026 15:40
@snejus
snejus force-pushed the type-metadata-source-plugins branch from 20145a4 to dab3a68 Compare August 19, 2026 15:40
@snejus
snejus force-pushed the type-api-export-plugins branch from 7494176 to 87da1ca Compare August 20, 2026 08:58
@snejus
snejus force-pushed the type-metadata-source-plugins branch from dab3a68 to 38f9195 Compare August 20, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beatport beatport plugin chroma chroma plugin deezer deezer plugin discogs discogs plugin listenbrainz listenbrainz plugin mbsubmit mbsubmit plugin spotify spotify plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants