Username lives in .env only: drop bgg_username from config.toml

load_config no longer reads a bgg_username toml key — BGG_USERNAME in
the environment is its single home (public, but the account should have
exactly one). Docs, messages, and tests updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-02 13:36:22 -04:00
parent 8e3cdc145f
commit abf7181475
6 changed files with 18 additions and 25 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ Straight-on, one shelf (or part of one) per shot, close enough that spine text i
## Bring your own shelves
This repo doubles as its author's live pipeline, so `data/` ships with his real artifacts — extracted titles, matches, and 2018 collection snapshots — and `config.toml` carries his username (your `BGG_USERNAME` in `.env` overrides it). Before running against *your* shelves, clear the data:
This repo doubles as its author's live pipeline, so `data/` ships with his real artifacts — extracted titles, matches, and 2018 collection snapshots. Before running against *your* shelves, clear the data:
```sh
rm data/*.csv data/*.json data/*.xml data/STUB_DATA.marker
+2 -9
View File
@@ -1,12 +1,5 @@
# Non-secret configuration for bggpipe. Secrets (ANTHROPIC_API_KEY,
# BGG_PASSWORD, BGG_API_TOKEN) come from env vars only and must never
# appear here.
# The BGG username isn't a secret (it's public on your profile), so it may
# live here — but BGG_USERNAME from .env OVERRIDES it, and since upload
# needs BGG_USERNAME anyway, .env alone is enough. Cloners: change or
# clear this.
bgg_username = "ewagoner"
# Non-secret knobs for bggpipe. Everything account-related — including
# your BGG username — lives in .env (see .env.example), not here.
photos_dir = "photos"
data_dir = "data"
+5 -5
View File
@@ -1,8 +1,9 @@
"""Configuration: config.toml at the project root, env vars override.
"""Configuration: non-secret knobs from config.toml at the project root.
Secrets (ANTHROPIC_API_KEY, BGG_PASSWORD) are never stored here — they are
read from the environment at the point of use and must never be written to
disk or logs.
Everything account-related lives in the environment (.env via direnv):
secrets (ANTHROPIC_API_KEY, BGG_PASSWORD, BGG_API_TOKEN) because they must
never touch disk or logs, and BGG_USERNAME — public, but kept there so the
account has exactly one home.
"""
from __future__ import annotations
@@ -46,7 +47,6 @@ def load_config(path: Path | None = None) -> Config:
if p.exists():
raw = tomllib.loads(p.read_text())
known = {
"bgg_username": str,
"photos_dir": Path,
"data_dir": Path,
"model": str,
+1 -1
View File
@@ -499,7 +499,7 @@ def run_upload(
def _run_verify(cfg: Config, client: BGGClient | None, log_path: Path) -> None:
if not cfg.bgg_username:
typer.echo("--verify needs bgg_username (config.toml or BGG_USERNAME).")
typer.echo("--verify needs BGG_USERNAME in the environment.")
return
client = client or BGGClient(cfg.cache_dir, cfg.rate_limit_seconds)
try:
+7 -7
View File
@@ -13,19 +13,19 @@ def test_defaults_when_no_file(tmp_path, monkeypatch):
def test_reads_toml(tmp_path, monkeypatch):
monkeypatch.delenv("BGG_USERNAME", raising=False)
p = tmp_path / "config.toml"
p.write_text(
'bgg_username = "someone"\ndata_dir = "elsewhere"\nrate_limit_seconds = 3\n'
)
p.write_text('data_dir = "elsewhere"\nrate_limit_seconds = 3\n')
cfg = load_config(p)
assert cfg.bgg_username == "someone"
assert cfg.data_dir == Path("elsewhere")
assert cfg.rate_limit_seconds == 3.0
assert cfg.matches_path == Path("elsewhere/matches.csv")
def test_env_overrides_toml(tmp_path, monkeypatch):
def test_username_comes_from_env_only(tmp_path, monkeypatch):
# the account has exactly one home: BGG_USERNAME in the environment —
# a bgg_username key in config.toml is deliberately ignored
p = tmp_path / "config.toml"
p.write_text('bgg_username = "from_toml"\n')
monkeypatch.setenv("BGG_USERNAME", "from_env")
cfg = load_config(p)
assert cfg.bgg_username == "from_env"
assert load_config(p).bgg_username == "from_env"
monkeypatch.delenv("BGG_USERNAME")
assert load_config(p).bgg_username == ""
+2 -2
View File
@@ -1,7 +1,7 @@
"""The one test allowed to touch the real BGG API. Read-only, skipped by
default; run with: uv run pytest --run-live -m live
Needs bgg_username in config.toml and BGG_API_TOKEN in the environment
Needs BGG_USERNAME and BGG_API_TOKEN in the environment
(register at https://boardgamegeek.com/applications).
"""
@@ -20,7 +20,7 @@ from bggpipe.config import load_config
def test_fetch_own_collection_read_only(tmp_path: Path) -> None:
cfg = load_config()
if not cfg.bgg_username:
pytest.skip("set bgg_username in config.toml to run the live smoke test")
pytest.skip("set BGG_USERNAME to run the live smoke test")
if not os.environ.get("BGG_API_TOKEN"):
pytest.skip("set BGG_API_TOKEN to run the live smoke test")