Skip to content

feat(esm_catalog): PR-B2 — queryables endpoints (OGC CQL2 filter schema)#1491

Open
siligam wants to merge 1 commit into
esm-catalog/pr-b1-serve-corefrom
esm-catalog/pr-b2-queryables
Open

feat(esm_catalog): PR-B2 — queryables endpoints (OGC CQL2 filter schema)#1491
siligam wants to merge 1 commit into
esm-catalog/pr-b1-serve-corefrom
esm-catalog/pr-b2-queryables

Conversation

@siligam

@siligam siligam commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Provenance: this implementation is substantially Paul Gierz's work, carried over from his esm-tools-plus/simcat/pgierz-workbench prototype branch (commits Mar–Apr 2026). This PR ports it, largely as-is, into the reviewable stack.

  • Adds api/queryables.py: fully dynamic property discovery from live DuckDB data — no hardcoded property lists; works for NetCDF global attrs, namelist params, HPC info, and future extensions automatically
  • Adds api/validation.py: is_safe_property_name() SQL injection guard used before any property name is interpolated into SQL
  • Wires /queryables and /collections/{id}/queryables into app.py with QueryablesCache (5-minute TTL)
  • STAC Browser's "Additional filters" CQL2 builder uses these endpoints to populate dropdown enum values

What's deferred

PR Content
B3 /experiments hierarchy routes + paleo time presets
B4 /catalogs federation API + auth middleware

Test plan

  • CI green on 3.9 + 3.12
  • GET /queryables → 200, has $schema, type: object, properties with datetime
  • GET /collections/{id}/queryables → 200, scoped to collection
  • GET /collections/no-such/queryables → 404
  • Landing page links include OGC queryables rel
  • Each collection response has queryables link

🤖 Generated with Claude Code

@siligam
siligam force-pushed the esm-catalog/pr-b1-serve-core branch from 7cf3c66 to 646d914 Compare June 17, 2026 12:13
@siligam
siligam force-pushed the esm-catalog/pr-b2-queryables branch from e061a3b to 4a672c8 Compare June 17, 2026 12:13
@siligam
siligam force-pushed the esm-catalog/pr-b1-serve-core branch from 646d914 to 75ce248 Compare June 17, 2026 15:59
@siligam
siligam force-pushed the esm-catalog/pr-b2-queryables branch from 4a672c8 to 57699a2 Compare June 17, 2026 15:59
@siligam
siligam force-pushed the esm-catalog/pr-b1-serve-core branch from 75ce248 to f01c336 Compare June 17, 2026 16:34
@siligam
siligam force-pushed the esm-catalog/pr-b2-queryables branch from 57699a2 to ad0c766 Compare June 17, 2026 16:34
…ctions/{id}/queryables)

Adds OGC CQL2 queryables support required for STAC Browser's "Additional
filters" builder:
- api/queryables.py: fully dynamic property discovery via DuckDB DISTINCT queries;
  handles nml:parameters, collection-level props, GHG unit info, paleo display sort
- api/validation.py: is_safe_property_name() SQL-injection guard used by queryables
- api/app.py: wires /queryables + /collections/{id}/queryables with QueryablesCache
- 11 new tests (101 total); no new dependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@siligam
siligam force-pushed the esm-catalog/pr-b2-queryables branch from ad0c766 to aa0bcc5 Compare June 17, 2026 17:03
@siligam

siligam commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto the corrected PR-0 base (#1483) — test relocation to tests/test_esm_catalog/, restored dedicated CI workflow at the new path, and a couple of CI fixes (doctest-collection exclusion, eval_type_backport for pydantic on Python 3.9). No change to this PR's own diff/scope. CI is green.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant