Examples & smoke tests skill (eo-processor)
Use this skill to add or update examples that serve two purposes:
- User onboarding: small, readable scripts that demonstrate “how do I use this?”
- Smoke testing: quick, repeatable end-to-end checks that catch integration breakage (Rust ↔ PyO3 ↔ Python API).
Examples are not a substitute for unit tests. They’re a second line of defense and a first line of comprehension.
Where this skill applies
Primary directory:
Common example files in this repo:
examples/basic_usage.py
examples/xarray_dask_usage.py
examples/spectral_indices_extended.py
examples/temporal_operations.py
examples/zonal_stats_example.py
examples/README.md
When to activate
Activate this skill when you:
- Add a new public function or change an existing one
- Modify behavior that examples rely on (dtype/shape rules, NaN handling, epsilon rules)
- Need a quick confirmation that the compiled extension, Python exports, and runtime behavior line up
- Want to provide a minimal “copy/paste runnable” onboarding path
- Need to demonstrate a workflow from
WORKFLOWS.md in executable form
Do not activate when:
- You’re only refactoring internals with no user-visible API impact (unless it might break runtime wiring)
Design goals (what “good” looks like)
A good example is:
- Runnable:
python examples/<file>.py works in the repo’s standard dev environment
- Small and focused: demonstrates one concept (or a tightly-related set), not the entire library
- Deterministic enough: uses fixed seeds for random data and avoids flaky assertions
- Honest: no claims about features that don’t exist; no placeholder TODOs
- Aligned with public API: imports from
eo_processor as users would
- Light on dependencies: uses only core deps unless the example explicitly targets an optional stack (xarray/dask)
A bad example is:
- Too big to read
- Depends on local data files without telling the user
- Requires niche libraries without documenting them
- Prints pages of output without meaning
- Quietly passes while doing the wrong thing
Example types to create (pick the smallest one that fits)
Type A: “Hello world” onboarding script
Use when introducing a new user-facing function.
Characteristics:
- Small arrays (1D or 2D)
- Clear printed output (min/max/mean, a small preview)
- A short explanation in comments
- No complex dependencies
Example topics:
- Spectral indices (NDVI/NDWI/…)
- Masking utilities
- Simple temporal aggregations
Type B: Smoke test script for integration
Use when you need a quick end-to-end check that users can run.
Characteristics:
- Imports the public API exactly as users do:
from eo_processor import ...
- Exercises the main code path (compiled extension)
- Validates invariants:
- shape preserved
- dtype as expected (or at least float)
- finite results (or NaN behavior is explicitly expected)
- Exits non-zero on failure (use
assert or explicit checks)
Important:
- Keep it fast (seconds, not minutes).
- Avoid huge arrays unless specifically testing performance.
Type C: “Workflow” example script
Use when demonstrating multi-step pipelines (e.g., temporal compositing + index + morphology).
Characteristics:
- A few logical steps, each with a comment header
- Prints intermediate summaries (shape/dtype/min/max/percentiles)
- Avoids large IO; uses synthetic data unless the repo explicitly includes sample data
Type D: Optional-stack example (xarray/dask)
Use only when:
- the feature is about
xr.apply_ufunc, dask parallelism, or chunk behavior
- the dependency is documented clearly at the top of the example
Characteristics:
- A small chunked array to keep runtime short
- Emphasizes correct usage patterns (
xr.apply_ufunc, dask="parallelized", etc.)
- Avoids requiring a distributed cluster (local threads is enough)
Step-by-step workflow
Step 1: Decide the example’s purpose and audience
Write down, in one sentence:
- “This example is for ____ and demonstrates ____.”
Also decide:
- Does it target beginners (Type A) or is it a smoke/integration check (Type B)?
Step 2: Choose file naming and placement
Rules:
- Put examples in
examples/.
- Prefer descriptive names (e.g.,
ndmi_example.py, masking_example.py).
- If updating, prefer editing an existing related example rather than creating duplicates.
Step 3: Write the script with a consistent structure
Recommended structure:
Header comment:
- what it demonstrates
- how to run it
- optional dependencies (if any)
Imports:
numpy first (almost always)
eo_processor imports next
- optional packages last
Deterministic input:
- use
np.random.default_rng(seed) if randomness is needed
- keep sizes modest (e.g., 256x256 or similar)
Compute:
- call the function(s) under test
Validate invariants:
assert out.shape == in.shape
assert np.isfinite(out).all() where appropriate
- if NaNs are expected: assert their presence and explain why
Print a human-readable summary:
- dtype, shape
- min/max/mean
- small preview slice if helpful (
out[:3, :3])
Exit cleanly:
- if using asserts, Python will raise on failure
Step 4: Keep outputs stable
Guidelines:
- Prefer summaries over full arrays.
- If printing numeric summaries, consider rounding for readability.
- Seed randomness so results don’t change unexpectedly.
Step 5: Update examples/README.md if appropriate
If you add a new example or make a meaningful change:
- Add a short bullet:
- what it demonstrates
- how to run it
- notes about optional deps
Assertions and correctness guidance
Examples can include lightweight checks, but avoid heavy logic.
Recommended checks:
- Shape preservation
- Basic finiteness (when contract expects it)
- Known-value sanity for tiny hand-constructed arrays (best for onboarding)
Avoid in examples:
- Tight tolerance comparisons against complex baselines (put those in
tests/)
- Large exhaustive test matrices (again,
tests/)
If you need stronger correctness validation:
- Add/extend a
tests/test_*.py unit test, and keep the example focused on usability.
Dependency discipline
Default dependency set for most examples
Optional dependencies (only when needed)
xarray, dask[array] for xarray/dask examples
- Any ML libs only for ML-specific demos (keep optional and documented)
Rules:
- If an example needs optional deps, say so at the top with install hints.
- Don’t introduce new dependencies solely for an example unless the repo already supports them.
Common pitfalls (avoid)
- Importing private/internal modules instead of the public API
- Using huge arrays that make examples slow or memory-heavy
- Relying on local files without documenting where to get them
- Silent failures (no asserts, no meaningful output)
- Flaky results due to unseeded randomness
- Examples drifting out of sync with
README.md and stubs
“Definition of done” for a new/updated example
You’re done when:
Suggested cookbook patterns (choose one)
Pattern 1: Minimal onboarding
- Tiny inputs (hand-coded arrays)
- Known outputs or easy-to-interpret summaries
Pattern 2: Small realistic raster
- Synthetic 2D arrays (e.g., 256x256 reflectance in [0, 1])
- Print min/max/mean and a tiny window
Pattern 3: Smoke test mode
- Minimal runtime
- Assertions + short summary
- Clear failure signal
Local references (repo)
- Examples directory:
examples/
- Example index:
examples/README.md
- User docs:
README.md, QUICKSTART.md, WORKFLOWS.md
- Engineering rules:
AGENTS.md
- Public API surface:
python/eo_processor/__init__.py, python/eo_processor/__init__.pyi
- Tests:
tests/
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: examples-and-smoke-tests3description: Create and maintain runnable examples under examples/ for onboarding and smoke testing. Use when adding/changing public APIs, when you need a quick “does it work end-to-end?” script, or when updating examples/README.md to match the current eo-processor API. Use when this capability is needed.4---56# Examples & smoke tests skill (eo-processor)78Use this skill to add or update **examples** that serve two purposes:9101. **User onboarding**: small, readable scripts that demonstrate “how do I use this?”112. **Smoke testing**: quick, repeatable end-to-end checks that catch integration breakage (Rust ↔ PyO3 ↔ Python API).1213Examples are not a substitute for unit tests. They’re a *second line of defense* and a *first line of comprehension*.1415---1617## Where this skill applies1819Primary directory:20- `examples/`2122Common example files in this repo:23- `examples/basic_usage.py`24- `examples/xarray_dask_usage.py`25- `examples/spectral_indices_extended.py`26- `examples/temporal_operations.py`27- `examples/zonal_stats_example.py`28- `examples/README.md`2930---3132## When to activate3334Activate this skill when you:35- Add a new public function or change an existing one36- Modify behavior that examples rely on (dtype/shape rules, NaN handling, epsilon rules)37- Need a quick confirmation that the compiled extension, Python exports, and runtime behavior line up38- Want to provide a minimal “copy/paste runnable” onboarding path39- Need to demonstrate a workflow from `WORKFLOWS.md` in executable form4041Do not activate when:42- You’re only refactoring internals with no user-visible API impact (unless it might break runtime wiring)4344---4546## Design goals (what “good” looks like)4748A good example is:49- **Runnable**: `python examples/<file>.py` works in the repo’s standard dev environment50- **Small and focused**: demonstrates one concept (or a tightly-related set), not the entire library51- **Deterministic enough**: uses fixed seeds for random data and avoids flaky assertions52- **Honest**: no claims about features that don’t exist; no placeholder TODOs53- **Aligned with public API**: imports from `eo_processor` as users would54- **Light on dependencies**: uses only core deps unless the example explicitly targets an optional stack (xarray/dask)5556A bad example is:57- Too big to read58- Depends on local data files without telling the user59- Requires niche libraries without documenting them60- Prints pages of output without meaning61- Quietly passes while doing the wrong thing6263---6465## Example types to create (pick the smallest one that fits)6667### Type A: “Hello world” onboarding script68Use when introducing a new user-facing function.6970Characteristics:71- Small arrays (1D or 2D)72- Clear printed output (min/max/mean, a small preview)73- A short explanation in comments74- No complex dependencies7576Example topics:77- Spectral indices (NDVI/NDWI/…)78- Masking utilities79- Simple temporal aggregations8081### Type B: Smoke test script for integration82Use when you need a quick end-to-end check that users can run.8384Characteristics:85- Imports the public API exactly as users do: `from eo_processor import ...`86- Exercises the main code path (compiled extension)87- Validates invariants:88 - shape preserved89 - dtype as expected (or at least float)90 - finite results (or NaN behavior is explicitly expected)91- Exits non-zero on failure (use `assert` or explicit checks)9293Important:94- Keep it fast (seconds, not minutes).95- Avoid huge arrays unless specifically testing performance.9697### Type C: “Workflow” example script98Use when demonstrating multi-step pipelines (e.g., temporal compositing + index + morphology).99100Characteristics:101- A few logical steps, each with a comment header102- Prints intermediate summaries (shape/dtype/min/max/percentiles)103- Avoids large IO; uses synthetic data unless the repo explicitly includes sample data104105### Type D: Optional-stack example (xarray/dask)106Use only when:107- the feature is about `xr.apply_ufunc`, dask parallelism, or chunk behavior108- the dependency is documented clearly at the top of the example109110Characteristics:111- A small chunked array to keep runtime short112- Emphasizes correct usage patterns (`xr.apply_ufunc`, `dask="parallelized"`, etc.)113- Avoids requiring a distributed cluster (local threads is enough)114115---116117## Step-by-step workflow118119### Step 1: Decide the example’s purpose and audience120Write down, in one sentence:121- “This example is for ____ and demonstrates ____.”122123Also decide:124- Does it target beginners (Type A) or is it a smoke/integration check (Type B)?125126### Step 2: Choose file naming and placement127Rules:128- Put examples in `examples/`.129- Prefer descriptive names (e.g., `ndmi_example.py`, `masking_example.py`).130- If updating, prefer editing an existing related example rather than creating duplicates.131132### Step 3: Write the script with a consistent structure133134Recommended structure:1351361. Header comment:137 - what it demonstrates138 - how to run it139 - optional dependencies (if any)1401412. Imports:142 - `numpy` first (almost always)143 - `eo_processor` imports next144 - optional packages last1451463. Deterministic input:147 - use `np.random.default_rng(seed)` if randomness is needed148 - keep sizes modest (e.g., 256x256 or similar)1491504. Compute:151 - call the function(s) under test1521535. Validate invariants:154 - `assert out.shape == in.shape`155 - `assert np.isfinite(out).all()` where appropriate156 - if NaNs are expected: assert their presence and explain why1571586. Print a human-readable summary:159 - dtype, shape160 - min/max/mean161 - small preview slice if helpful (`out[:3, :3]`)1621637. Exit cleanly:164 - if using asserts, Python will raise on failure165166### Step 4: Keep outputs stable167Guidelines:168- Prefer summaries over full arrays.169- If printing numeric summaries, consider rounding for readability.170- Seed randomness so results don’t change unexpectedly.171172### Step 5: Update `examples/README.md` if appropriate173If you add a new example or make a meaningful change:174- Add a short bullet:175 - what it demonstrates176 - how to run it177 - notes about optional deps178179---180181## Assertions and correctness guidance182183Examples can include lightweight checks, but avoid heavy logic.184185Recommended checks:186- Shape preservation187- Basic finiteness (when contract expects it)188- Known-value sanity for tiny hand-constructed arrays (best for onboarding)189190Avoid in examples:191- Tight tolerance comparisons against complex baselines (put those in `tests/`)192- Large exhaustive test matrices (again, `tests/`)193194If you need stronger correctness validation:195- Add/extend a `tests/test_*.py` unit test, and keep the example focused on usability.196197---198199## Dependency discipline200201### Default dependency set for most examples202- `numpy`203- `eo_processor`204205### Optional dependencies (only when needed)206- `xarray`, `dask[array]` for xarray/dask examples207- Any ML libs only for ML-specific demos (keep optional and documented)208209Rules:210- If an example needs optional deps, say so at the top with install hints.211- Don’t introduce new dependencies solely for an example unless the repo already supports them.212213---214215## Common pitfalls (avoid)216217- Importing private/internal modules instead of the public API218- Using huge arrays that make examples slow or memory-heavy219- Relying on local files without documenting where to get them220- Silent failures (no asserts, no meaningful output)221- Flaky results due to unseeded randomness222- Examples drifting out of sync with `README.md` and stubs223224---225226## “Definition of done” for a new/updated example227228You’re done when:229- [ ] The example runs from the repo root with the standard dev environment230- [ ] It imports from `eo_processor` (public API) rather than internals231- [ ] It includes small but meaningful invariant checks (shape/dtype/finite as appropriate)232- [ ] Output is readable and stable (seeded randomness if used)233- [ ] `examples/README.md` is updated if a new example was added or behavior changed234- [ ] If the example reflects a new/changed public API, docs and stubs are also aligned (see `docs-and-release` and `python-api-surface` skills)235236---237238## Suggested cookbook patterns (choose one)239240### Pattern 1: Minimal onboarding241- Tiny inputs (hand-coded arrays)242- Known outputs or easy-to-interpret summaries243244### Pattern 2: Small realistic raster245- Synthetic 2D arrays (e.g., 256x256 reflectance in [0, 1])246- Print min/max/mean and a tiny window247248### Pattern 3: Smoke test mode249- Minimal runtime250- Assertions + short summary251- Clear failure signal252253---254255## Local references (repo)256- Examples directory: `examples/`257- Example index: `examples/README.md`258- User docs: `README.md`, `QUICKSTART.md`, `WORKFLOWS.md`259- Engineering rules: `AGENTS.md`260- Public API surface: `python/eo_processor/__init__.py`, `python/eo_processor/__init__.pyi`261- Tests: `tests/`262263---264> Converted and distributed by [TomeVault](https://tomevault.io/claim/bnjam) — claim your Tome and manage your conversions.265<!-- tomevault:4.0:skill_md:2026-04-14 -->