Load service settings from environment variables
Python · Python · beginner · greenfield
Adds the settings loader the service reads at startup. Treats blank values as unset so a stray `PORT=` in a compose file falls back to the default instead of crashing, validates the port range, and accepts the usual spellings for boolean flags. Errors name the offending variable so a bad deploy fails loudly and legibly.
Requirements
- Implement `load_settings(env)` where `env` is a mapping of string names to string values (like `os.environ`); return a dict with keys `port`, `debug`, `allowed_hosts`.
- A variable that is missing, empty, or whitespace-only counts as **unset** and takes its default: `port` 8000, `debug` `False`, `allowed_hosts` `[]`.
- `PORT`: parse with Python's `int()` (so surrounding whitespace is tolerated); a value `int()` rejects raises `ValueError` naming the variable, and a parsed value outside 1–65535 also raises `ValueError`.
- `DEBUG`: case-insensitive; `1/true/yes/on` mean `True`, `0/false/no/off` mean `False`, anything else raises `ValueError` naming the variable.
- `ALLOWED_HOSTS`: comma-separated; strip whitespace around each entry and drop empty entries (so `"a, ,b,"` yields `['a', 'b']`).
Files touched
- app/config/settings.py
--- app/config/settings.py
+TRUE_WORDS = {"1", "true", "yes", "on"}
+FALSE_WORDS = {"0", "false", "no", "off"}
+
+
+def _get(env, name):
+ """Return the trimmed value, or None if missing, empty, or whitespace-only."""
+ raw = env.get(name)
+ if raw is None:
+ return None
+ value = raw.strip()
+ return value or None
+
+
+def load_settings(env):
+ raw_port = _get(env, "PORT")
+ if raw_port is None:
+ port = 8000
+ else:
+ try:
+ port = int(raw_port)
+ except ValueError:
+ raise ValueError(f"PORT must be an integer, got {raw_port!r}")
+ if not 1 <= port <= 65535:
+ raise ValueError(f"PORT must be between 1 and 65535, got {port}")
+
+ raw_debug = _get(env, "DEBUG")
+ if raw_debug is None:
+ debug = False
+ else: