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:
@@ -73,7 +73,7 @@ Straight-on, one shelf (or part of one) per shot, close enough that spine text i
|
|||||||
|
|
||||||
## Bring your own shelves
|
## 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
|
```sh
|
||||||
rm data/*.csv data/*.json data/*.xml data/STUB_DATA.marker
|
rm data/*.csv data/*.json data/*.xml data/STUB_DATA.marker
|
||||||
|
|||||||
+2
-9
@@ -1,12 +1,5 @@
|
|||||||
# Non-secret configuration for bggpipe. Secrets (ANTHROPIC_API_KEY,
|
# Non-secret knobs for bggpipe. Everything account-related — including
|
||||||
# BGG_PASSWORD, BGG_API_TOKEN) come from env vars only and must never
|
# your BGG username — lives in .env (see .env.example), not here.
|
||||||
# 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"
|
|
||||||
|
|
||||||
photos_dir = "photos"
|
photos_dir = "photos"
|
||||||
data_dir = "data"
|
data_dir = "data"
|
||||||
|
|||||||
@@ -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
|
Everything account-related lives in the environment (.env via direnv):
|
||||||
read from the environment at the point of use and must never be written to
|
secrets (ANTHROPIC_API_KEY, BGG_PASSWORD, BGG_API_TOKEN) because they must
|
||||||
disk or logs.
|
never touch disk or logs, and BGG_USERNAME — public, but kept there so the
|
||||||
|
account has exactly one home.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -46,7 +47,6 @@ def load_config(path: Path | None = None) -> Config:
|
|||||||
if p.exists():
|
if p.exists():
|
||||||
raw = tomllib.loads(p.read_text())
|
raw = tomllib.loads(p.read_text())
|
||||||
known = {
|
known = {
|
||||||
"bgg_username": str,
|
|
||||||
"photos_dir": Path,
|
"photos_dir": Path,
|
||||||
"data_dir": Path,
|
"data_dir": Path,
|
||||||
"model": str,
|
"model": str,
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ def run_upload(
|
|||||||
|
|
||||||
def _run_verify(cfg: Config, client: BGGClient | None, log_path: Path) -> None:
|
def _run_verify(cfg: Config, client: BGGClient | None, log_path: Path) -> None:
|
||||||
if not cfg.bgg_username:
|
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
|
return
|
||||||
client = client or BGGClient(cfg.cache_dir, cfg.rate_limit_seconds)
|
client = client or BGGClient(cfg.cache_dir, cfg.rate_limit_seconds)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ def test_defaults_when_no_file(tmp_path, monkeypatch):
|
|||||||
def test_reads_toml(tmp_path, monkeypatch):
|
def test_reads_toml(tmp_path, monkeypatch):
|
||||||
monkeypatch.delenv("BGG_USERNAME", raising=False)
|
monkeypatch.delenv("BGG_USERNAME", raising=False)
|
||||||
p = tmp_path / "config.toml"
|
p = tmp_path / "config.toml"
|
||||||
p.write_text(
|
p.write_text('data_dir = "elsewhere"\nrate_limit_seconds = 3\n')
|
||||||
'bgg_username = "someone"\ndata_dir = "elsewhere"\nrate_limit_seconds = 3\n'
|
|
||||||
)
|
|
||||||
cfg = load_config(p)
|
cfg = load_config(p)
|
||||||
assert cfg.bgg_username == "someone"
|
|
||||||
assert cfg.data_dir == Path("elsewhere")
|
assert cfg.data_dir == Path("elsewhere")
|
||||||
assert cfg.rate_limit_seconds == 3.0
|
assert cfg.rate_limit_seconds == 3.0
|
||||||
assert cfg.matches_path == Path("elsewhere/matches.csv")
|
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 = tmp_path / "config.toml"
|
||||||
p.write_text('bgg_username = "from_toml"\n')
|
p.write_text('bgg_username = "from_toml"\n')
|
||||||
monkeypatch.setenv("BGG_USERNAME", "from_env")
|
monkeypatch.setenv("BGG_USERNAME", "from_env")
|
||||||
cfg = load_config(p)
|
assert load_config(p).bgg_username == "from_env"
|
||||||
assert cfg.bgg_username == "from_env"
|
monkeypatch.delenv("BGG_USERNAME")
|
||||||
|
assert load_config(p).bgg_username == ""
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""The one test allowed to touch the real BGG API. Read-only, skipped by
|
"""The one test allowed to touch the real BGG API. Read-only, skipped by
|
||||||
default; run with: uv run pytest --run-live -m live
|
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).
|
(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:
|
def test_fetch_own_collection_read_only(tmp_path: Path) -> None:
|
||||||
cfg = load_config()
|
cfg = load_config()
|
||||||
if not cfg.bgg_username:
|
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"):
|
if not os.environ.get("BGG_API_TOKEN"):
|
||||||
pytest.skip("set BGG_API_TOKEN to run the live smoke test")
|
pytest.skip("set BGG_API_TOKEN to run the live smoke test")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user