fix(edr): implement pygeoapi's instance contract - #876
Open
jirhiker wants to merge 1 commit into
Open
Conversation
/ogcapi/collections/waterlevels/instances returned a 500:
TypeError: 'NotImplementedError' object is not iterable
pygeoapi calls p.instances() and p.instance(id); this provider spelled
them get_instances() and get_instance(). Because BaseEDRProvider
*returns* a NotImplementedError instance from both rather than raising
one, the mismatch was silent -- /instances iterated that object, and
/instances/{id}/... validated the id against a truthy object, so any
identifier at all was accepted. Transducer deployments have therefore
never been reachable as EDR instances, which is exactly what the
waterlevels description advertises. Renamed; nothing called the old
names.
The behave feature that covers this has existed since ADR3 and caught it
on the first run, but it is tagged @backend @edr with no @production, and
CI runs "@backend and @production and not @Skip" -- so it has never run
there. Tagged @production.
Two fixture defects were hiding behind that, both of which made the
chemistry scenarios fail once the feature ran:
* The fixture seeded chemistry as observation rows, but d9e0f1a2b3c4
rebuilt ogc_water_chemistry over the legacy NMA_* tables, so the
collection saw nothing -- a 400 (pH is not a known parameter) and a
204. It now seeds NMA_Chemistry_SampleInfo/NMA_FieldParameters and
refreshes the materialized view, without which the rows stay invisible
anyway.
* ogc_water_chemistry gates on the thing's release_status as well as the
sample's, and wells seed as 'draft', so the fixture published no
chemistry at all. It now promotes its own well to public.
Full production behave suite: 85 scenarios, 0 failed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #874 (which is itself stacked on #866). Base is
chore/actively-monitored-wells-description; GitHub retargets as the chain merges.The bug
GET /ogcapi/collections/waterlevels/instancesreturns 500:pygeoapi calls
p.instances()andp.instance(id).WaterEDRProviderspelled themget_instances()andget_instance(), so it overrode nothing.What made this silent rather than loud:
BaseEDRProvider.instances/instancereturn aNotImplementedErrorinstance rather than raising one. So/instancesiterated that object (the TypeError above), and/instances/{id}/…validated the id against a truthy object — meaning any instance identifier was accepted, valid or not.Transducer deployments have therefore never been reachable as EDR instances, which is precisely what the collection advertises:
Renamed to the contract pygeoapi actually calls. Nothing in the repo referenced the old names.
Why CI never caught it
tests/features/edr-water-data.featurehas covered this since ADR3 — "Transducer deployments are exposed as EDR instances" — and it fails on the first run. But the feature is tagged@backend @edrwith no@production, and CI runs@backend and @production and not @skip. It has never run there. Now tagged@production.Two fixture defects that were hiding behind that
Turning the feature on exposed both; the chemistry scenarios failed with 400 and 204:
observationrows, butd9e0f1a2b3c4rebuiltogc_water_chemistryover the legacyNMA_*tables, so the collection saw nothing —parameter-name=pHcame back "Invalid parameter-name" (400) because the provider's field list was empty, and location queries returned 204. It now seedsNMA_Chemistry_SampleInfo/NMA_FieldParameters, and refreshes the materialized view, without which the rows stay invisible regardless.draft.ogc_water_chemistrygates on the thing'srelease_statusas well as the sample's, and seeded wells default todraft, so the fixture could never publish chemistry. It now promotes its own well to public.Verification
uv run behave tests/features/edr-water-data.feature→ 8 scenarios, 0 failed (was 5 failed / 1 errored)DROP_AND_REBUILD_DB=1 uv run behave tests/features --tags="@backend and @production and not @skip"→ 9 features, 85 scenarios, 0 faileduv run pytest --ignore=tests/transfers→ 1098 passed, 81 skipped, 6 xpassedpre-commit(black, flake8) cleanNew unit tests assert the contract directly — that
instances/instanceare overridden and are not the base implementations — so a future rename cannot silently reintroduce this.Flagged, not fixed here
ogc_waterlevelsfilters on the observation'srelease_statusonly, whileogc_water_chemistryalso requires the parent thing to be public. A draft well with public readings is therefore published through EDR water levels but not through EDR chemistry. That inconsistency is a publication-policy decision, not a bug to settle in this PR — it belongs with BDMS-988 (A9, define the publication predicate per layer family).🤖 Generated with Claude Code