feat(discovery): SimilaritySource protocol + FakeSimilaritySource
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ from typing import Callable
|
|||||||
|
|
||||||
from lyra_worker.browser import ArtistHit, ReleaseGroupInfo
|
from lyra_worker.browser import ArtistHit, ReleaseGroupInfo
|
||||||
from lyra_worker.probe import ProbeResult
|
from lyra_worker.probe import ProbeResult
|
||||||
|
from lyra_worker.similarity.base import SimilarArtist
|
||||||
from lyra_worker.types import Candidate, DownloadResult, MBTarget, Quality
|
from lyra_worker.types import Candidate, DownloadResult, MBTarget, Quality
|
||||||
|
|
||||||
_QUALITIES = {
|
_QUALITIES = {
|
||||||
@@ -90,3 +91,19 @@ class FakeAudioProbe:
|
|||||||
self._r = ProbeResult(artist=artist, album=album, fmt=fmt, quality_class=quality_class)
|
self._r = ProbeResult(artist=artist, album=album, fmt=fmt, quality_class=quality_class)
|
||||||
def probe(self, path: str) -> ProbeResult:
|
def probe(self, path: str) -> ProbeResult:
|
||||||
return self._r
|
return self._r
|
||||||
|
|
||||||
|
|
||||||
|
class FakeSimilaritySource:
|
||||||
|
"""In-memory SimilaritySource for tests. `similar` maps seed mbid -> [SimilarArtist]."""
|
||||||
|
|
||||||
|
name = "fake"
|
||||||
|
|
||||||
|
def __init__(self, similar=None, healthy=True):
|
||||||
|
self._similar = dict(similar or {})
|
||||||
|
self._healthy = healthy
|
||||||
|
|
||||||
|
def health(self) -> bool:
|
||||||
|
return self._healthy
|
||||||
|
|
||||||
|
def similar_artists(self, mbid: str) -> list[SimilarArtist]:
|
||||||
|
return list(self._similar.get(mbid, []))
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Protocol, runtime_checkable
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class SimilarArtist:
|
||||||
|
mbid: str
|
||||||
|
name: str
|
||||||
|
score: float
|
||||||
|
|
||||||
|
|
||||||
|
@runtime_checkable
|
||||||
|
class SimilaritySource(Protocol):
|
||||||
|
name: str
|
||||||
|
|
||||||
|
def health(self) -> bool:
|
||||||
|
"""Is this source reachable right now?"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def similar_artists(self, mbid: str) -> list[SimilarArtist]:
|
||||||
|
"""Artists similar to the given artist MBID (MBID-native)."""
|
||||||
|
...
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
from lyra_worker.adapters.fakes import FakeSimilaritySource
|
||||||
|
from lyra_worker.similarity.base import SimilarArtist, SimilaritySource
|
||||||
|
|
||||||
|
|
||||||
|
def test_fake_conforms_to_protocol_and_returns_similar():
|
||||||
|
src = FakeSimilaritySource(similar={"seed": [SimilarArtist("c1", "Cand", 0.9)]})
|
||||||
|
assert isinstance(src, SimilaritySource)
|
||||||
|
assert src.health() is True
|
||||||
|
assert src.similar_artists("seed") == [SimilarArtist("c1", "Cand", 0.9)]
|
||||||
|
assert src.similar_artists("unknown") == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_fake_can_report_unhealthy():
|
||||||
|
assert FakeSimilaritySource(healthy=False).health() is False
|
||||||
Reference in New Issue
Block a user