Gateway: config from env vars #2

Closed
opened 2026-08-09 20:31:47 +00:00 by hermes · 1 comment
Owner

Context

Gateway service (see #18). Configuration is injected entirely via env vars
so the same container image works anywhere.

Task

Create app/config.py returning a frozen dataclass, read from env:

  • APPLE_TEAM_ID (10-char team ID, JWT iss)
  • APPLE_KEY_ID (MusicKit key ID, JWT kid)
  • APPLE_KEY_PATH (path to the AuthKey_*.p8 private key file)
  • APPLE_SERVICES_ID (MusicKit Services ID / client_id)
  • SERVICE_TOKEN (bearer token the beets plugin uses on /api/v1/*)
  • GATEWAY_DB_PATH (default ./gateway.db)
  • GATEWAY_BASE_URL (external https URL of the deployment; used to build
    the login page and callback links)

Fail fast at startup: any missing required var aborts with a clear message
naming the variable (use sys.exit from the app factory or a pydantic
Settings with extra="forbid"; stdlib os.environ is fine too — keep it
dependency-light).

Acceptance criteria

  • Unit test: config parses a full env set; each missing required var
    produces an error mentioning the variable name.
  • SERVICE_TOKEN is never logged or exposed in any response.
## Context Gateway service (see #18). Configuration is injected entirely via env vars so the same container image works anywhere. ## Task Create `app/config.py` returning a frozen dataclass, read from env: - `APPLE_TEAM_ID` (10-char team ID, JWT `iss`) - `APPLE_KEY_ID` (MusicKit key ID, JWT `kid`) - `APPLE_KEY_PATH` (path to the `AuthKey_*.p8` private key file) - `APPLE_SERVICES_ID` (MusicKit Services ID / client_id) - `SERVICE_TOKEN` (bearer token the beets plugin uses on `/api/v1/*`) - `GATEWAY_DB_PATH` (default `./gateway.db`) - `GATEWAY_BASE_URL` (external https URL of the deployment; used to build the login page and callback links) Fail fast at startup: any missing required var aborts with a clear message naming the variable (use `sys.exit` from the app factory or a pydantic `Settings` with `extra="forbid"`; stdlib `os.environ` is fine too — keep it dependency-light). ## Acceptance criteria - Unit test: config parses a full env set; each missing required var produces an error mentioning the variable name. - `SERVICE_TOKEN` is never logged or exposed in any response.
Author
Owner

Done in coop/apple-music-gateway (commit be064de): app/config.py — frozen Config dataclass from env (APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_KEY_PATH, APPLE_SERVICES_ID, SERVICE_TOKEN, GATEWAY_DB_PATH default ./gateway.db, GATEWAY_BASE_URL). load_config() raises ConfigError naming every missing var; create_app() sys.exits at startup. SERVICE_TOKEN is repr=False, never logged or exposed. 13 tests pass (full-env parse, per-var missing-name check, DB-path default, token-never-in-repr, factory fail-fast).

Done in `coop/apple-music-gateway` (commit `be064de`): `app/config.py` — frozen `Config` dataclass from env (APPLE_TEAM_ID, APPLE_KEY_ID, APPLE_KEY_PATH, APPLE_SERVICES_ID, SERVICE_TOKEN, GATEWAY_DB_PATH default ./gateway.db, GATEWAY_BASE_URL). `load_config()` raises `ConfigError` naming every missing var; `create_app()` sys.exits at startup. SERVICE_TOKEN is `repr=False`, never logged or exposed. 13 tests pass (full-env parse, per-var missing-name check, DB-path default, token-never-in-repr, factory fail-fast).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coop/beets-appleplaylists#2
No description provided.