Half our incidents traced back to config: an env var typo'd to an empty string, a port that was actually the literal text "8080" compared against an int, a feature flag that was the string "false" (which is truthy). The naive prompt gives you os.environ["THING"] sprinkled everywhere and no validation.
So I wrote a prompt that produces a single typed, validated config object loaded once at startup, that fails loudly with every problem at once instead of one-at-a-time. Collecting all errors before exiting is what makes it pleasant, you fix the whole .env in one pass.
Do people prefer pydantic-settings for this or a hand-rolled dataclass loader? I lean dataclass to avoid the dependency for small tools.
Write a Python config module that loads all configuration once at startup into a single immutable, typed object, and validates it eagerly.
Requirements:
- Read from environment variables (and optionally a `.env` via a tiny parser, no hard dependency). Never read `os.environ` anywhere else in the codebase.
- Use a frozen `@dataclass` (or pydantic-settings if you justify the dependency). Every field is typed.
- Coerce and validate: ints are parsed and range-checked; booleans accept only {true,false,1,0,yes,no} case-insensitively (reject anything else, do NOT treat non-empty strings as True); URLs are format-checked; required fields with no default must be present.
- Collect ALL validation errors and report them together in one message, then `sys.exit(2)`. Do not stop at the first bad value.
- Secrets: fields marked secret must not appear in `repr`/logs (`repr=False` or masked).
- Provide sensible defaults for optional fields and document each field with a comment: name, type, default, purpose.
- Expose a single `load_config() -> Config` and a module-level singleton that's easy to override in tests.
Include a short example `.env` and a snippet showing what the error output looks like when three values are wrong at once.