MusicBrainz provider refactor and birthday/memoriam/anniversary recommendations#3833
MusicBrainz provider refactor and birthday/memoriam/anniversary recommendations#3833dmoo500 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends Music Assistant’s cross-type ProviderFeature dispatch so that metadata providers and plugin providers can participate in features like browse/recommendations/similar-* (building on the #3811 groundwork), and updates controllers/base classes plus tests accordingly.
Changes:
- Add
MusicAssistant.get_providers_supporting_feature(...)to retrieve providers supporting a feature across provider-type tiers with priority ordering. - Enable cross-type feature usage in controllers (e.g., browse root and recommendations aggregation; similar-artists endpoint; similar-tracks fallback to metadata/plugins).
- Add/extend base provider APIs (PluginProvider/MetadataProvider) for similar-* and recommendations, update demo plugin provider, and add unit tests.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
music_assistant/mass.py |
Adds get_providers_supporting_feature helper and removes plugin-specific feature query helper. |
music_assistant/controllers/music.py |
Uses cross-type provider lookup for browse root and recommendations; widens provider recommendation typing. |
music_assistant/controllers/media/tracks.py |
Adds metadata/plugin fallback for similar_tracks. |
music_assistant/controllers/media/artists.py |
Adds similar_artists API endpoint with music-first, metadata/plugin fallback dispatch. |
music_assistant/controllers/media/base.py |
Allows get_provider_item to call get_item on plugin providers (in addition to music providers). |
music_assistant/models/metadata_provider.py |
Adds cross-type feature stubs: similar tracks/artists + recommendations. |
music_assistant/models/plugin.py |
Adds cross-type feature stubs + playlist/get_item plumbing for plugins. |
music_assistant/models/music_provider.py |
Adds get_similar_artists abstract method to the MusicProvider base. |
music_assistant/providers/_demo_plugin_provider/__init__.py |
Documents/illustrates cross-type feature stubs and playlist plumbing for plugins. |
music_assistant/providers/qobuz/__init__.py |
Removes an unused/empty get_similar_artists stub. |
tests/test_cross_type_features.py |
Adds unit tests for provider ordering and cross-type dispatch behavior. |
|
I think the refactor should be one PR and the extra recommendations another. Also there are outstanding PRs which touch the metadata controller and this will mean problems later. I was planning on looking into doing this (so thanks for taking it on) but I was going to wait until all the other changes were merged. Edit: sorry I misread and this is the musicbrainz controller. Regardless, the PR should only be just that. And my last.fm provider also touches this. |
|
And why is the Qobuz provider getting touched here? edit: ok I see this is the result of #3811 . Once that is merged and this is rebased then split this into two. |
|
Keeping this as Draft until two upstream PRs are merged:
Once both are merged, I'll rebase and split this into two PRs:
|
Refactor the monolithic musicbrainz __init__.py into separate modules: - api_client.py: HTTP client with throttling and caching - models.py: MusicBrainz dataclasses (adds first_release_date to ReleaseGroup) - constants.py: shared config key constants - provider.py: MusicbrainzProvider metadata provider Implement ProviderFeature.RECOMMENDATIONS via a new RecommendationManager: - Birthday artists: library artists born on today's date - In memoriam artists: library artists who passed away on today's date - Album anniversaries: 5-year milestone release anniversaries for today's date Add 17 unit tests covering all recommendation types.
581a028 to
b4fa005
Compare
Summary
Refactors the MusicBrainz provider into a multi-file package and adds
ProviderFeature.RECOMMENDATIONSsupport.Refactor: monolithic
__init__.py→ multi-file packageThe existing
musicbrainz/__init__.py(~600 lines) is split into focused modules:api_client.pymodels.pyMusicBrainzArtist,MusicBrainzReleaseGroup, etc.)constants.pyprovider.pyMusicbrainzProvider(MetadataProvider)— all existing functionality preservedrecommendations.pyMusicBrainzRecommendationManager— new recommendation logicFeature: three recommendation types
All three scan the user's library and cross-reference MusicBrainz data:
life_span.begindate matches today's month/day, grouped by genre intoRecommendationFolders withmdi-cake-varianticon.life_span.enddate matches today's (only whenlife_span.ended == True), iconmdi-candle.first_release_datematches today, filtered to 5-year milestones only (5, 10, 15, … years ago), iconmdi-calendar-star. Each matching album becomes a playableRecommendationFolder.Implementation notes
begin:????-MM-DDreturns 0 results on the MA mirror, so the library-scan strategy is used: iterate library items, fetch individual MB records (30-day cached).MusicBrainzAPIClient.domain— addeddomain = "musicbrainz"class attribute required by the@use_cachedecorator.MusicBrainzReleaseGroup.first_release_date— new optional field populated from the existingrelease-group/{id}endpoint response.Tests
17 unit tests covering:
ended=Falseguard_build_artist_foldersgenre grouping, overrides, and "Other" bucketget_recommendationsintegration for all three types