refactor(server): extract library + collections routes + the provider registry (R3) (#866)

The library query surface (songs/albums/artists/stats/genres/tuning-names/
practice-suggestions), the provider list/art/sync endpoints, and collection CRUD
move to lib/routers/library.py. The registry itself — LibraryProviderRegistry,
LocalLibraryProvider, SmartCollectionProvider, the collection-provider lifecycle
(_sync/_unregister_collection_provider), and the shared query/collection helpers
(_library_filter_args, _split_csv, _sanitize_collection_rules, _safe_art_redirect_url,
the filter-key sets) — moves to lib/library_registry.py.

The PLUGIN CONTRACT is untouched: server.py still constructs the singleton
(LocalLibraryProvider needs meta_db), still exposes register_library_provider /
unregister_library_provider to plugins via plugin_context (with the per-plugin
ownership scoping in plugins/__init__.py), and injects the registry + local
provider into appstate. The router reads appstate.library_providers /
appstate.local_library_provider at call time; the provider classes are duck-typed
so no plugin imports a base class. Acyclic: library_registry imports
routers.art (for LocalLibraryProvider.get_art) + appstate, never server.

server.py: 3,692 -> 2,925 (-767).

Verified: pyflakes clean; ORDERED route table identical set (library block mounts
at one site — all exact/specific-path, no catch-all, no shadowing); full pytest
2397 passed (incl the plugin register/unregister + collection-as-provider tests).
eslint 0. Boot smoke: /api/library + providers list "local"; a created collection
surfaces as a `collection:N` provider through the seam; collection CRUD clean.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Byron Gamatos
2026-07-11 14:56:12 +02:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 9a58a55fe8
commit f09c4a217f
7 changed files with 932 additions and 789 deletions
+2 -1
View File
@@ -7,6 +7,7 @@ result, not stored songs.
"""
import importlib
import library_registry
import sys
import pytest
@@ -133,7 +134,7 @@ def test_collection_tolerates_corrupt_persisted_rules(client, server_mod):
('{"artist": [], "sort": [], "tunings": ["Drop D"]}', cid),
)
server_mod.meta_db.conn.commit()
server_mod._sync_collection_provider(server_mod.meta_db.get_collection(cid))
library_registry._sync_collection_provider(server_mod.meta_db.get_collection(cid))
r = client.get("/api/library", params={"provider": f"collection:{cid}"})
assert r.status_code == 200 # no 500/503 from bad rules