# `mgf-common` Examples

Runnable examples organised by **topic** and **layer**. Every script
is self-contained (uses `tempfile.TemporaryDirectory` for disk
side-effects, isolates env vars), runs in under a second, and is
smoke-tested in CI so the examples never drift from the API.

## Layout

```
examples/
├── 01_exceptions/         — typed hierarchy + subclassing + translation seam
├── 02_config/             — BaseAppSettings + make_settings_config + load/save
├── 03_logging/            — setup_logging + Redactor + structured fields
├── 04_observability/      — setup_otel + operation_span + trace correlation
├── 05_crash_reporting/    — report_now + sys/threading excepthooks
└── 06_full_app/           — a complete tiny CLI tying everything together
```

Each topic ships **three layers**, in increasing depth:

| File | Layer | Use it when… |
|---|---|---|
| `01_simple.py` | **Simple** — minimum viable use, ~15 lines | You want the elevator pitch: the smallest snippet that exercises the API |
| `02_practical.py` | **Practical** — realistic small app, ~50 lines, moderate comments | You're sketching how you'd wire it into a real project |
| `03_advanced.py` | **Advanced** — production-shaped, ~150+ lines, rich inline comments | You want to understand every choice + the standards rules each line implements |

## Run an example

```bash
# From the repo root, with mgf-common installed in your venv:
python examples/01_exceptions/01_simple.py

# Or via uv:
uv run python examples/03_logging/02_practical.py
```

Every script has a `main()` function and an
`if __name__ == "__main__":` guard, so they're also importable for
inspection without side-effects.

## CI smoke test

`tests/unit/test_examples.py` invokes every example as a subprocess
and asserts exit code 0. The subprocess shape gives full isolation
(no shared global state between examples) at ~50 ms per script —
the full sweep is under 2 s.

If you add a new example, the smoke test discovers it
automatically via the `examples/[0-9][0-9]_*/[0-9][0-9]_*.py` glob.

## Conventions every example follows

- **`main()` function** + `if __name__ == "__main__": main()` guard.
- **`tempfile.TemporaryDirectory`** for any disk side-effects (logs,
  crash reports, config files). The user's `~/.local/state/<app>/`
  is never touched.
- **`os.environ` mutations** scoped to the temp dir — `HOME`,
  `XDG_STATE_HOME`, `XDG_CONFIG_HOME` redirected before the example
  calls `mgf.common.configure(...)`.
- **`mgf.common.configure(app_name="example-<topic>", ...)`** at
  the start of every example that touches identity-derived paths
  (logging, crash reports, OTel service name).
- **Print observable output** so a human running the example sees
  evidence it worked (e.g., the path of the rotating log file, the
  text of a caught exception).

## Suggested reading order

If you're new to `mgf-common`:

1. `01_exceptions/01_simple.py` — the smallest possible use.
2. `01_exceptions/02_practical.py` — what a real subclass looks like.
3. `06_full_app/02_practical.py` — the headline integration.
4. The `03_advanced.py` file of whichever topic you'll touch first.

If you're an AI agent given a task that touches one of these areas,
the `03_advanced.py` for that topic is the dense reference — every
line is commented with the standards rule (DP-*, EH-*, LG-*, CF-*,
SC-*, AP-*) it implements.

## Cross-references

- The API surface every example uses: [`PUBLIC_API.md`](../PUBLIC_API.md).
- The standards each `03_advanced.py` cites: [`docs/standards/`](../docs/standards/).
- The full integration story for a real app: [`06_full_app/03_advanced.py`](06_full_app/03_advanced.py).
