Resolve degrades gracefully when BGG_API_TOKEN is missing
A 401 on an uncached title no longer aborts the run: cached titles resolve and save, blocked titles are listed with registration/token instructions and left out of matches.csv so a future run picks them up untouched. Supports the take-photos-now, resolve-later workflow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+17
-2
@@ -18,7 +18,7 @@ from pathlib import Path
|
||||
import typer
|
||||
from rapidfuzz import fuzz
|
||||
|
||||
from bggpipe.bgg_client import BGGClient
|
||||
from bggpipe.bgg_client import BGGAuthError, BGGClient
|
||||
from bggpipe.config import Config
|
||||
from bggpipe.models import GameVersion
|
||||
from bggpipe.normalize import normalize_title
|
||||
@@ -417,12 +417,20 @@ def run_resolve(
|
||||
|
||||
new_rows: list[MatchRow] = []
|
||||
skipped = 0
|
||||
blocked: list[str] = []
|
||||
for entry in entries:
|
||||
key = _row_key(entry.title_raw, ";".join(entry.source_photos))
|
||||
if key in existing:
|
||||
skipped += 1
|
||||
continue
|
||||
row = resolve_entry(client, entry)
|
||||
try:
|
||||
row = resolve_entry(client, entry)
|
||||
except BGGAuthError:
|
||||
# No API token yet: cached titles still resolve; the rest wait.
|
||||
# No row is written, so a future run picks them up untouched.
|
||||
blocked.append(entry.title_raw)
|
||||
typer.echo(f" {entry.title_raw!r} -> waiting on BGG API token")
|
||||
continue
|
||||
new_rows.append(row)
|
||||
detail = f"{row.bgg_name} ({row.bgg_id})" if row.bgg_id else "-"
|
||||
version = f" [{row.version_status}]" if row.version_status else ""
|
||||
@@ -438,4 +446,11 @@ def run_resolve(
|
||||
f"Resolved {len(new_rows)} title(s) ({summary or 'nothing new'}); "
|
||||
f"skipped {skipped} already in {cfg.matches_path}."
|
||||
)
|
||||
if blocked:
|
||||
typer.echo(
|
||||
f"\n{len(blocked)} title(s) are waiting on the BGG API "
|
||||
"(register at https://boardgamegeek.com/applications, then set "
|
||||
"BGG_API_TOKEN and re-run resolve — everything above is saved): "
|
||||
+ ", ".join(blocked)
|
||||
)
|
||||
return new_rows
|
||||
|
||||
@@ -294,3 +294,52 @@ def test_wrong_year_hint_never_drives_a_version(client):
|
||||
assert (row.match_status, row.bgg_id) == ("auto", 2529)
|
||||
assert row.version_status == "version_unknown"
|
||||
assert row.version_id is None
|
||||
|
||||
|
||||
# -- graceful degradation without a BGG token ---------------------------
|
||||
|
||||
|
||||
def test_run_resolve_saves_progress_when_token_missing(tmp_path):
|
||||
"""Cached titles resolve; uncached ones wait for the token instead of
|
||||
crashing the run and losing everything."""
|
||||
import shutil as _shutil
|
||||
|
||||
partial_cache = tmp_path / "cache"
|
||||
partial_cache.mkdir()
|
||||
for f in FIXTURES.glob("search_query=Catan-*"):
|
||||
_shutil.copy(f, partial_cache / f.name)
|
||||
|
||||
data_dir = tmp_path / "data"
|
||||
data_dir.mkdir()
|
||||
(data_dir / "titles.json").write_text(
|
||||
json.dumps(
|
||||
[
|
||||
{"title_raw": "Catan", "source_photos": ["a.jpg"]},
|
||||
{"title_raw": "Wingspan", "source_photos": ["a.jpg"]},
|
||||
]
|
||||
)
|
||||
)
|
||||
cfg = Config(data_dir=data_dir)
|
||||
unauthorized = BGGClient(
|
||||
cache_dir=partial_cache,
|
||||
transport=httpx.MockTransport(
|
||||
lambda req: httpx.Response(401, text="Unauthorized")
|
||||
),
|
||||
)
|
||||
|
||||
rows = run_resolve(cfg, client=unauthorized)
|
||||
assert [r.title_raw for r in rows] == ["Catan"] # cached one made it
|
||||
|
||||
with cfg.matches_path.open(newline="") as f:
|
||||
saved = list(csv.DictReader(f))
|
||||
assert len(saved) == 1 # blocked title left for a future run
|
||||
|
||||
# future run (fixtures now "recorded"): picks up only the blocked title
|
||||
full = BGGClient(
|
||||
cache_dir=FIXTURES,
|
||||
transport=httpx.MockTransport(
|
||||
lambda req: (_ for _ in ()).throw(AssertionError("network"))
|
||||
),
|
||||
)
|
||||
rows2 = run_resolve(cfg, client=full)
|
||||
assert [r.title_raw for r in rows2] == ["Wingspan"]
|
||||
|
||||
Reference in New Issue
Block a user