Skip to content

Add Bandcamp Music Provider#2871

Merged
MarvinSchenkel merged 24 commits intomusic-assistant:devfrom
ALERTua:bc
Jan 15, 2026
Merged

Add Bandcamp Music Provider#2871
MarvinSchenkel merged 24 commits intomusic-assistant:devfrom
ALERTua:bc

Conversation

@ALERTua
Copy link
Copy Markdown
Contributor

@ALERTua ALERTua commented Dec 22, 2025

Bandcamp Music Provider

This PR adds support for Bandcamp Music Provider based on bandcamp_async_api Python library.

API

  • This Provider is based on bandcamp_async_api that I developed specifically for this.
  • The API library has extensive tests both using mocks and the real data and covers everything the API touches.
  • I encountered zero 5** or 429 errors during my testing, so I did not need to implement rate limiting. But I can if you need me to.

Provider

server_repo: ALERTua/fork_music_assistant_server@bc
  • You need the Bandcamp identity cookie only to browse your library. All other operations (search) do not need the identity.

Documentation

  • Documentation PR

Maintaining the Provider Code in the Future

  • I will happily maintain this provider and the code related to it in the future
  • I will happily monitor and review other pull requests in case they are related to the code of this provider
  • I would appreciate creating a label for this provider that I can subscribe to, which allows me to filter related issues

Digressions

edit: PR for most of these items: #2871

  • Music Assistant Server can be developed on Windows, or, should I say, on any OS. But there are caveats that can be easily fixed:
    • The pre-commit config uses scripts/run-in-env.sh. This is unneeded due to uv. uv run pre-commit run executes the same calls but on any OS.
    • The pre-commit config uses python3 -m ... which should also be substituted by uv run -m ...
    • Many pre-commit checks can be replaced with the "official" ones from uv, ruff, pre-commit, mypy.
(Spoiler) My resulting working pre-commit config that does everything that the original one does, but on any OS
repos:
  - repo: local
    hooks:
      # gen_requirements_all modifies files so it has to be first
      - id: gen_requirements_all
        name: gen_requirements_all
        entry: uv run -m scripts.gen_requirements_all
        pass_filenames: false
        language: system
        types: [text]
        files: ^(music_assistant/.+/manifest\.json|pyproject\.toml|\.pre-commit-config\.yaml|scripts/gen_requirements_all\.py)$

      - id: ruff-check
        name: 🐶 Ruff Linter
        language: system
        types: [python]
        entry: uv run ruff check --fix
        require_serial: true
        stages: [pre-commit, pre-push, manual]

      - id: ruff-format
        name: 🐶 Ruff Formatter
        language: system
        types: [python]
        entry: uv run ruff format
        require_serial: true
        stages: [pre-commit, pre-push, manual]

      - id: check-ast
        name: 🐍 Check Python AST
        language: system
        types: [python]
        entry: uv run check-ast

      - id: check-case-conflict
        name: 🔠 Check for case conflicts
        language: system
        entry: uv run check-case-conflict

      - id: check-docstring-first
        name: ℹ️  Check docstring is first
        language: system
        types: [python]
        entry: uv run check-docstring-first

      - id: check-executables-have-shebangs
        name: 🧐 Check that executables have shebangs
        language: system
        types: [text, executable]
        entry: uv run check-executables-have-shebangs
        stages: [pre-commit, pre-push, manual]

      - id: check-json
        name: { Check JSON files
        language: system
        types: [json]
        entry: uv run check-json
        files: ^(music_assistant/.+/manifest\.json)|(tests/providers/.+/fixtures/.+\.json)$

      - id: check-merge-conflict
        name: 💥 Check for merge conflicts
        language: system
        types: [text]
        entry: uv run check-merge-conflict

      - id: check-symlinks
        name: 🔗 Check for broken symlinks
        language: system
        types: [symlink]
        entry: uv run check-symlinks

      - id: check-toml
        name: ✅ Check TOML files
        language: system
        types: [toml]
        entry: uv run check-toml

      - id: codespell
        name: ✅ Check code for common misspellings
        language: system
        types: [text]
        entry: uv run codespell

      - id: detect-private-key
        name: 🕵️ Detect Private Keys
        language: system
        types: [text]
        entry: uv run detect-private-key

      - id: end-of-file-fixer
        name: ⮐ Fix End of Files
        language: system
        types: [text]
        entry: uv run end-of-file-fixer
        stages: [pre-commit, pre-push, manual]

      - id: no-commit-to-branch
        name: 🛑 Don't commit to stable branch
        language: system
        entry: uv run no-commit-to-branch
        pass_filenames: false
        always_run: true
        args:
          - --branch=stable

      - id: trailing-whitespace
        name: ✄ Trim Trailing Whitespace
        language: system
        types: [text]
        entry: uv run trailing-whitespace-fixer
        stages: [pre-commit, pre-push, manual]

      - id: mypy
        name: mypy
        entry: uv run mypy
        language: system
        types: [python]
        require_serial: true
        pass_filenames: false
  • In pre-commit fixes, the end of lines is taken from the system. It should be fixed as LF in pyproject.toml and .gitattributes to allow for development on any OS.
  • WSL2 is not needed to either develop or test the project. Everything I tested works natively on Windows.
  • I could try implementing all this if you want in a separate PR.
  • The documentation does not have templates for pages. If I want to add a provider or player, I have to copy the existing page and edit it.
  • I am happy with Music Assistant, and I am happy to be useful in expanding this great project.
  • I am thrilled with SendSpin protocol, and I already use it everywhere I can on my Chromecast devices. Thank you for this <3

@ALERTua
Copy link
Copy Markdown
Contributor Author

ALERTua commented Dec 22, 2025

OK, I forgot mypy. Fixing all issues. Sorry.

@OzGav OzGav added this to the 2.8.0 milestone Dec 23, 2025
@ALERTua ALERTua changed the title add Bandcamp Music Provider Add Bandcamp Music Provider Dec 23, 2025
- is_streaming_provider is now True
- catching and raising exceptions revamp
- remove redundant stream content type
# Conflicts:
#	requirements_all.txt
@ALERTua ALERTua requested a review from OzGav December 26, 2025 09:28
@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Dec 29, 2025

@ALERTua there is a test failure unfortunately

@ALERTua
Copy link
Copy Markdown
Contributor Author

ALERTua commented Dec 29, 2025

I am sorry, I don't know how this happened. On my way to fix the tests v_v

- Add error handling for missing streaming links in BandcampProvider.
- Enhance error handling and update test assertions for Bandcamp provider.
@ALERTua
Copy link
Copy Markdown
Contributor Author

ALERTua commented Dec 29, 2025

@OzGav the tests are fixed. Sorry I forgot to run tests after a refactoring v_v.

@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Jan 3, 2026

Looks pretty good. The only thing I would say is quite a few ignores being used which we don’t see in the other providers so it would be better to properly type the code (other than the arguments in get_config_entries which are pretty much always unused and ignored)

@ALERTua
Copy link
Copy Markdown
Contributor Author

ALERTua commented Jan 3, 2026

Done. Thank you for your feedback.

@MarvinSchenkel
Copy link
Copy Markdown
Contributor

Few comments from my side, but all in all, awesome job on this new music provider <3.

As for your pre-commit fixes. Feel free to open a separate PR for this :).

- Remove search limit configuration.
- CONF_TOP_TRACKS_LIMIT moved to advanced config category
- Update test to use `DEFAULT_TOP_TRACKS_LIMIT` constant.
Copy link
Copy Markdown
Contributor

@MarvinSchenkel MarvinSchenkel left a comment

Choose a reason for hiding this comment

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

Awesome addition to the music providers, thanks a lot @ALERTua 🎉

@MarvinSchenkel MarvinSchenkel merged commit 177d236 into music-assistant:dev Jan 15, 2026
6 checks passed
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.

4 participants