Level 1 / Project 09 - JSON Settings Loader¶
Home: README
Learn Your Way¶
| Read | Build | Watch | Test | Review | Visualize | Try |
|---|---|---|---|---|---|---|
| Concept | This project | — | Quiz | Flashcards | — | Browser |
Estimated time: 30 minutes
Focus¶
- load config and fallback behavior
Why this project exists¶
Load application settings from a JSON file, merge them with sensible defaults, and validate required keys. You will learn json.loads(), dictionary merging with {**defaults, **overrides}, and config validation patterns.
Run (copy/paste)¶
Use <repo-root> as the folder containing this repository's README.md.
cd <repo-root>/projects/level-1/09-json-settings-loader
python project.py --input data/sample_input.txt
pytest -q
Expected terminal output¶
=== Settings Loader ===
app_name: LearnPython (from file)
debug: True (from file)
port: 8080 (default)
host: localhost (default)
Loaded 4 settings (2 from file, 2 defaults)
5 passed
Expected artifacts¶
data/output.json- Passing tests
- Updated
notes.md
Checkpoint: Baseline code runs and all tests pass. Commit your work before continuing.
Alter it (required) — Extension¶
- Add a
--validateflag that checks whether all required keys exist without running the main logic. - Add environment variable overrides (e.g.
APP_PORT=9090overrides"port": 8080from the file). - Re-run script and tests.
Break it (required) — Core¶
- Use a settings file with invalid JSON (missing a closing brace) -- does
load_json()raiseValueError? - Use a settings file missing a required key like
"host"-- doesvalidate_settings()catch it? - Use a file that exists but is completely empty -- does the loader crash or fall back to defaults?
Fix it (required) — Core¶
- Ensure
load_json()wrapsjson.loads()in a try/except and raisesValueErrorwith context. - Handle empty files by treating them as empty dicts (fall back to all defaults).
- Add a test for the empty-file case.
Checkpoint: All modifications done, tests still pass. Good time to review your changes.
Explain it (teach-back)¶
- Why does
merge_settings()create a new dict with{**defaults, **overrides}instead of modifying in place? - What does
json.loads()do and how does it differ fromjson.load()(with no 's')? - Why keep a
DEFAULTSdict at module level instead of hardcoding defaults inside functions? - Where would settings loaders appear in real software (web servers, CLI tools, microservices)?
Mastery check¶
You can move on when you can: - run baseline without docs, - explain one core function line-by-line, - break and recover in one session, - keep tests passing after your change.
Related Concepts¶
| ← Prev | Home | Next → |
|---|---|---|