Skip to content

Add two public DAM price endpoints, annual samples, and ESR snapshots - #2

Open
kvkenyon wants to merge 1 commit into
feat/public-foundationfrom
feat/public-retrieval
Open

Add two public DAM price endpoints, annual samples, and ESR snapshots#2
kvkenyon wants to merge 1 commit into
feat/public-foundationfrom
feat/public-retrieval

Conversation

@kvkenyon

@kvkenyon kvkenyon commented Sep 5, 2026

Copy link
Copy Markdown
Owner

TinyERCOT had no opt-in client backed by verified current public responses. This PR adds bounded retrieval for two DAM price endpoints, public annual DAM samples, and the rolling website ESR feed. All three legacy runtime files remain byte-identical to the audit base. This PR stacks on #1 (feat/public-foundation, 4b26c8a91efbba668dbbc40f564bbe812d4ae792). Keep both PRs unmerged.

Exact coverage

Generated typed API coverage is 2 operations in 2 products out of 243 observed public data paths across 98 product namespaces. NP4-190-CD is one narrow verified slice. NP4-188-CD is the second. The two website adapters are separate from this API denominator. The legacy 102 endpoints do not count as current verified coverage.

Evidence class Scope
Typed installed-client current fetch NP4-190-CD: two pages of two HB_HOUSTON rows for 2026-09-04, plus a fetch after explicit ID-token reacquisition. NP4-188-CD: two REGUP rows for that date.
Typed installed-client historical fetch One oldest-first row from each API endpoint returned 2023-12-13. Public annual report 13060: four rows each from 2010/Dec_1 and 2026/Aug; truncation and receipt-cache reuse verified. No complete-history claim.
Typed installed-client live fetch One rolling website ESR snapshot with source offset/epoch and freshness checks. This does not implement the four-second Public Data API.
Real source retrieval only NP4-190-CD product metadata. Retained public fixture, no product-metadata method.
Fixture-only behavior Rate limits, partial-token response retry, expiry/401/403, malformed response/archive formats, cache mutation, repeated pages, and DST transitions. Faults were simulated, not induced on ERCOT.
Deferred schema The other 241 observed data paths and all generic API archive/bundle operations. Stage 0 recorded 40 missing and 203 unverified cached schemas; only two current contracts are verified here.
Restricted Secure, Certified, EWS, private telemetry/bids/COP/awards, participant settlements, and customer data. No requests or entitlement workarounds.
Unavailable Retired total-AS-offer and SASM sources; unavailable hourly-load year 2001.

docs/public-retrieval.md enumerates all 39 audited public/conditional/restricted/unavailable source families and their EMIL or website IDs. coverage() exposes all 257 observed operations and those family states offline. No whole broad family is marked covered. Current field pins, fixture transformations, exact public response hashes, and installed-client receipts are committed in compact form.

Behavior and limits

New imports live under tinyercot.public. The new clients use separate row models and errors. They have explicit credentials, synchronized token acquisition, a 60-second expiry margin, one 401 reacquisition, bounded retry/pacing, and request/byte limits. Default imports and metadata require no credentials. Annual downloads require a public listing entry and receipt cache; decoding selects one worksheet and at most 1,000 rows. Source publication time, retrieval time, and local market fields remain separate. Unknown/null API row schemas fail closed. No as-of revision or full-filter/schema-epoch contract is claimed.

Authorized ERCOT Public API authentication did occur in this expanded milestone. Credential and token values were not printed or retained in source, fixtures, receipts, commits, or PR text. Only two selected annual files were downloaded, once during discovery and once through the installed adapter; subsequent probes used the cache. No historical bulk extraction, restricted request, paid access, forecaster work, no-mistakes run, or merge occurred. Foundation PR #1 remains public-metadata-only and unmerged.

Primary sources: ERCOT current API export, authentication guide, known limits, public annual DAM product, and ESR website feed.

Validation

941 passed, 1 skipped on Python 3.14.0 and 3.11.14. The normal suite blocks sockets; the real integration entry point is opt-in and skipped by default. Both generators reproduce pinned output. Scoped Ruff and format checks pass for 26 authored Python files. Build and isolated installed-wheel smoke checks pass, including offline metadata without the XLSX extra. The installed wheel separately passed real current/historical API, token reacquisition, ESR, and annual-file/cache checks.

Exact commands:

uv run python tools/generate_client.py --check
uv run python tools/generate_public.py --check
uv run --extra files pytest -q
UV_PROJECT_ENVIRONMENT=/tmp/tinyercot-py311 uv run --frozen --python 3.11 --extra files pytest -q
uv run ruff check tools/generate_client.py tools/generate_public.py tools/probe_public.py tinyercot/catalog.py tinyercot/public tests
uv run ruff format --check tools/generate_client.py tools/generate_public.py tools/probe_public.py tinyercot/catalog.py tinyercot/public tests
uv build
uv export --frozen --no-dev --no-emit-project --output-file /tmp/tinyercot-requirements.txt
uv pip sync --python /tmp/tinyercot-wheel/bin/python /tmp/tinyercot-requirements.txt
uv pip install --python /tmp/tinyercot-wheel/bin/python --no-deps dist/tinyercot-0.2.2-py3-none-any.whl
/tmp/tinyercot-wheel/bin/python -I tests/wheel_smoke.py
uv venv /tmp/tinyercot-retrieval-wheel
uv pip install --python /tmp/tinyercot-retrieval-wheel/bin/python 'dist/tinyercot-0.2.2-py3-none-any.whl[files]'
uv pip install --python /tmp/tinyercot-retrieval-wheel/bin/python --reinstall --no-deps dist/tinyercot-0.2.2-py3-none-any.whl
/tmp/tinyercot-retrieval-wheel/bin/python -I tests/wheel_smoke.py
/tmp/tinyercot-retrieval-wheel/bin/python -I tools/probe_public.py --live --credentials-file /Users/kevin/.treehouse/tinyercot-1bad13/1/tinyercot/.env --output /Users/kevin/.treehouse/tinyercot-1bad13/1/tinyercot/.local-evidence/installed
git diff --check
git diff --cached --check

Reviewed git status, staged diff, and remote PR base before push. Existing unrelated example/frozen-file Ruff findings stay excluded as documented in Stage 0. No unrelated work was discarded or reformatted. Google-style Python documentation was reviewed. Deferred limits include async retrieval, automatic polling, all-history extraction, other source families, schema epochs, as-of revisions, and package-wide PEP 561 typing. No blocker remains for this bounded milestone.

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