checkpoint: working 10-artist batch with log-normalized ranking
This commit is contained in:
1 parent
332331e7ef
commit
5d441ffe7c
10 files changed
+35107
No files matched your search
@@ -0,0 +1,109 @@
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import sqlite3
|
||||
import requests
|
||||
from typing import Dict, Any
|
||||
from rapidfuzz import fuzz
|
||||
|
||||
class MusicBrainzVerifier:
|
||||
"""
|
||||
Cross-references artist names against MusicBrainz with local SQLite caching.
|
||||
Free, no API key required (Rate limit: 1 request/second).
|
||||
"""
|
||||
BASE_URL = "https://musicbrainz.org/ws/2/artist"
|
||||
|
||||
def __init__(self, db_path: str = ".cache/verifiers_cache.sqlite", app_name: str = "HiffiArtistIntelligence", version: str = "1.0"):
|
||||
self.headers = {
|
||||
"User-Agent": f"{app_name}/{version} ( contact@superlabs.co )"
|
||||
}
|
||||
self.last_call_time = 0.0
|
||||
self.db_path = db_path
|
||||
os.makedirs(os.path.dirname(self.db_path), exist_ok=True)
|
||||
self._init_db()
|
||||
|
||||
def _init_db(self):
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
conn.execute("""
|
||||
CREATE TABLE IF NOT EXISTS musicbrainz_cache (
|
||||
artist_name TEXT PRIMARY KEY,
|
||||
data_json TEXT,
|
||||
cached_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
|
||||
def _get_cache(self, name: str) -> Dict[str, Any]:
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT data_json FROM musicbrainz_cache WHERE artist_name = ?", (name.lower(),))
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
return json.loads(row[0])
|
||||
return None
|
||||
|
||||
def _set_cache(self, name: str, data: Dict[str, Any]):
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
conn.execute(
|
||||
"INSERT OR REPLACE INTO musicbrainz_cache (artist_name, data_json) VALUES (?, ?)",
|
||||
(name.lower(), json.dumps(data))
|
||||
)
|
||||
|
||||
def _rate_limit(self):
|
||||
elapsed = time.time() - self.last_call_time
|
||||
if elapsed < 1.0:
|
||||
time.sleep(1.0 - elapsed)
|
||||
self.last_call_time = time.time()
|
||||
|
||||
def verify_artist(self, name: str) -> Dict[str, Any]:
|
||||
if not name or not name.strip():
|
||||
return {"verified": False, "confidence": 0.0, "reason": "empty_name"}
|
||||
|
||||
cleaned_name = name.strip()
|
||||
|
||||
# Check local cache first
|
||||
cached = self._get_cache(cleaned_name)
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
self._rate_limit()
|
||||
query = f'artist:"{cleaned_name}"'
|
||||
params = {"query": query, "fmt": "json", "limit": 3}
|
||||
|
||||
try:
|
||||
resp = requests.get(self.BASE_URL, headers=self.headers, params=params, timeout=10)
|
||||
if resp.status_code != 200:
|
||||
result = {"verified": False, "confidence": 0.0, "status_code": resp.status_code}
|
||||
return result
|
||||
|
||||
data = resp.json()
|
||||
artists = data.get("artists", [])
|
||||
if not artists:
|
||||
result = {"verified": False, "confidence": 0.0, "reason": "not_found"}
|
||||
self._set_cache(cleaned_name, result)
|
||||
return result
|
||||
|
||||
best_match = artists[0]
|
||||
mb_name = best_match.get("name", "")
|
||||
match_score = fuzz.token_sort_ratio(cleaned_name.lower(), mb_name.lower())
|
||||
|
||||
confidence = round(match_score / 100.0, 2)
|
||||
is_verified = confidence >= 0.80
|
||||
|
||||
result = {
|
||||
"verified": is_verified,
|
||||
"confidence": confidence,
|
||||
"mbid": best_match.get("id"),
|
||||
"matched_name": mb_name,
|
||||
"disambiguation": best_match.get("disambiguation", ""),
|
||||
"country": best_match.get("country", ""),
|
||||
"type": best_match.get("type", "")
|
||||
}
|
||||
self._set_cache(cleaned_name, result)
|
||||
return result
|
||||
except Exception as e:
|
||||
return {"verified": False, "confidence": 0.0, "error": str(e)}
|
||||
|
||||
if __name__ == "__main__":
|
||||
verifier = MusicBrainzVerifier()
|
||||
print("Testing MusicBrainz Caching...")
|
||||
print(verifier.verify_artist("Kendrick Lamar"))
|
||||
Reference in new issue
Block a user