Each dive is a labelled join key: a position, a depth, a date, and its provenance. That key is enough to make the world's siloed ocean databases talk to each other — no warehouse required.
Ocean temperature lives at PacIOOS. Biodiversity lives at OBIS and WoRMS. Specimen records live at NOAA's deep-sea coral database. Earthquakes live at USGS. Four schemas, four query languages, four silos. The thing that lets them join is a shared spatial-temporal key — and every Pisces dive is exactly that: (lat, lon, depth, date), with a citation.
So pisces treats a dive as an executable object. Ask it a question and it federates the databases for you — and every answer comes back not as a bare number but as a Reading: a value together with its source, the exact request that produced it, and its licence. A fact is never divorced from its documentation history.
Every data source is an adapter — one function implementing one interface:
That is the whole surface area. Add one adapter and every dive gains that dimension at once — indeed any point on Earth does, not just Pisces dives. A pull request to the toolkit is a contribution to the science.
Add pisces/adapters/yourname.py with a @register-decorated fetch().
value + source + url + licence. Out of coverage? Return a documented gap, don't raise.
fetch_all() now includes your source for all 428 dives — and the map, fauna, and per-dive code.
Shipping now, stdlib-only so a generated dive script runs anywhere with zero dependencies:
Wanted — each makes the deep-sea record a little less siloed:
The toolkit lives in the repository under pisces/, alongside the data and the site — no backend, no service. Every per-dive page's “This dive as code” download is a self-contained version of the same thing; the toolkit is where the shared logic accrues. See pisces/CONTRIBUTING.md.