Skip to content

Improvement of MusicMe music provider for API signin, and fix the parsing of the "streamable" fields and playlists ids#4029

Open
mintgrey wants to merge 7 commits into
music-assistant:devfrom
mintgrey:dev
Open

Improvement of MusicMe music provider for API signin, and fix the parsing of the "streamable" fields and playlists ids#4029
mintgrey wants to merge 7 commits into
music-assistant:devfrom
mintgrey:dev

Conversation

@mintgrey
Copy link
Copy Markdown

@mintgrey mintgrey commented May 29, 2026

What does this implement/fix?

This PR adds/corrects 3 functionalities as discussed in Discussion #5421 :

  • It adds a method for signin by API call rather than HTTP authentification by website, and a checkbox for user choice is provided at initialisation of the provider by a ConfigEntry entry
  • It fixes a problem that leads to unavalaible albums or tracks, by modifying the test on "streamable" fied in JSON response
  • It fixes a problem that leads to unplayable playlist, by modifying the way to parse the playlist id to have a full numeric id without an annoying prefix

The modifications are tested locally for several days on my HA/MA installation, and it works like a charm !

Types of changes

  • Bugfix (non-breaking change which fixes an issue) — bugfix
  • New feature (non-breaking change which adds functionality) — new-feature
  • Enhancement to an existing feature — enhancement
  • New music/player/metadata/plugin provider — new-provider
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) — breaking-change
  • Refactor (no behaviour change) — refactor
  • Documentation only — documentation
  • Maintenance / chore — maintenance
  • CI / workflow change — ci
  • Dependencies bump — dependencies

Checklist

  • The code change is tested and works locally.
  • pre-commit run --all-files passes.
  • pytest passes, and tests have been added/updated under tests/ where applicable.
  • For changes to shared models, the companion PR in music-assistant/models is linked.
  • For changes affecting the UI, the companion PR in music-assistant/frontend is linked.
  • I have read and complied with the project's AI Policy for any AI-assisted contributions.

P.S. This is my first PR on github, I'm listening for any advice or correction !

@MarvinSchenkel
Copy link
Copy Markdown
Contributor

@JulienDeveaux could you please have a look at this?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Improves the existing MusicMe music provider by adding an API-based signin alternative to the existing scraped-web login, broadening the "streamable" filter from == 2 to != 0 so albums/tracks flagged with other non-zero values are not hidden, and stripping the pl- prefix from playlist IDs so the dataservice playlist endpoints work for those entries.

Changes:

  • Adds a SIGNIN_BY_API boolean config entry and a new _signin_by_api method that authenticates by hitting /medialibrary/signin via _api_get.
  • Replaces all streamable == 2 checks with streamable != 0 in search, browse, recommendations, top tracks, radio track selection, and parsers.
  • Normalizes playlist IDs in _parse_playlist by stripping a pl- prefix; updates one streaming test fixture to match the new streamable semantics.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
music_assistant/providers/musicme/constants.py Adds the SIGNIN_BY_API config key constant.
music_assistant/providers/musicme/init.py Registers the new boolean config entry for API signin.
music_assistant/providers/musicme/provider.py Branches init between web login and new _signin_by_api; loosens streamable checks; strips pl- from playlist ids.
tests/providers/musicme/test_streaming.py Updates a fixture from streamable: 1 to streamable: 0 to match new semantics.
Comments suppressed due to low confidence (1)

music_assistant/providers/musicme/provider.py:60

  • [PROBLEM] The import group is no longer alphabetically sorted (SIGNIN_BY_API should come after PARTNER_ID). Ruff/isort in pre-commit will flag this.
from .constants import (
    SIGNIN_BY_API,
    CLIENT_JSON,
    DATASERVICE_BASE,
    LOGIN_URL,
    PARTNER_ID,
    STREAM_BASE,
    VALID_ID_RE,
    WEB_BASE,

Comment on lines +782 to +790
async def _signin_by_api(self) -> None:
login = self.config.get_value(CONF_USERNAME)
password = self.config.get_value(CONF_PASSWORD)

response = await self._api_get(
f"/medialibrary/signin"
f"?channel=65777&lang=fr&format=json&client=%7B%22type%22%3A%22desktop-web%22%2C%22context%22%3A%22pro.bib.musicme.com%22%7D"
f"&key=sKTBA7ybW3nvCUQ6&nocrypt=0&login={login}&password={password}"
)
Comment on lines +786 to +790
response = await self._api_get(
f"/medialibrary/signin"
f"?channel=65777&lang=fr&format=json&client=%7B%22type%22%3A%22desktop-web%22%2C%22context%22%3A%22pro.bib.musicme.com%22%7D"
f"&key=sKTBA7ybW3nvCUQ6&nocrypt=0&login={login}&password={password}"
)
Comment on lines +792 to +803
if response and "results" in response:
results = response.get("results", {})
if results and "user" in results:
self._user_id = results.get("user").get("id")

if not self._user_id:
msg = "Login failed — no user.id in MusicMe API response"
raise LoginFailed(msg)

self.logger.info(
"Successfully logged in to MusicMe"
)
Comment on lines +45 to +51
ConfigEntry(
key=SIGNIN_BY_API,
type=ConfigEntryType.BOOLEAN,
label="Signin by API",
required=False,
description="If checked, the signin will be made by API call, if unchecked, login will be made by HTTP authentication.",
),
Comment on lines 573 to 577
item_id=barcode,
provider_domain=self.domain,
provider_instance=self.instance_id,
available=album_obj.get("streamable", 0) == 2,
available=album_obj.get("streamable", 0) != 0,
audio_format=AudioFormat(
def _parse_playlist(self, playlist_obj: dict[str, Any]) -> Playlist:
"""Parse a MusicMe playlist object to a Music Assistant Playlist."""
playlist_id = str(playlist_obj.get("id", ""))
playlist_id = (str(playlist_obj.get("id", ""))).removeprefix("pl-")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants