Skip to content

feat(python): expose historical and latest endpoint wrappers - #143

Merged
mHjertaker merged 8 commits into
mainfrom
feat/expose-latest-and-historical-endpoint-wrappers
Aug 5, 2026
Merged

feat(python): expose historical and latest endpoint wrappers#143
mHjertaker merged 8 commits into
mainfrom
feat/expose-latest-and-historical-endpoint-wrappers

Conversation

@joakimia

@joakimia joakimia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Extracted from #132. Wires grid_insights and capacity_monitoring endpoints that already existed in the generated API clients through HeimdallApiClient, and fixes what surfaced when those wrappers were first exercised against the API.

New endpoint wrappers

  • Historical: get_currents, get_conductor_temperatures, get_icing, get_sag_and_clearance, get_apparent_power, get_heimdall_dlrs, get_heimdall_aars, get_circuit_ratings
  • Latest: get_latest_apparent_power, get_icing_forecast

Fixes

  • get_currents raised ImportError at call time — the client method imported a wrapper that was never written. The import is function-local, so linting and package import stayed green.
  • Windowed endpoints returned 400: timestamps must be Z-suffixed UTC, but datetime.isoformat() always emits a +00:00 offset. Normalized via as_zulu() in _timestamps.py, applied in the hand-written wrappers so regeneration cannot overwrite it. Naive input is treated as UTC; other offsets are converted.
  • Forwarded parameters the wrappers dropped: unit_system on get_conductor_temperatures, quantity on the three rating endpoints, and since on the latest endpoints that accept it.

Generator

openapi-python-client formats its output via post-hooks that call the bare ruff executable, which silently no-ops when ruff is not on PATH — leaving generated code unformatted and turning a 3-file change into a 54-file diff. The hooks now run through python -m ruff, and unformatted output fails generate-module-client.ps1 rather than reaching a commit. Both modules are regenerated with that in place.

Tests

  • tests/integration/ — windowed and latest endpoints in separate files, covering unit_system, quantity, since, timestamp normalization across naive / UTC / offset input, and the 30-day window cap. Endpoints skip rather than fail on 404 so an asset without data for a metric cannot mask a wiring bug.
  • tests/unit/ — resolves every lazily-imported wrapper and covers as_zulu. These run on pull requests, where the integration suite does not.

Test plan

  • poetry run ruff check .
  • poetry run ruff format --check .
  • poetry run pytest tests/unit — 95 passed
  • poetry run pytest -m integration — 38 passed, 13 skipped
  • poetry build

AI usage

  • AI-assisted. Claude Opus 5 reviewed the original wrapper commit, wrote the fixes and tests, and diagnosed the regeneration diff. Findings were verified against the API before fixing.

…allApiClient

Wraps grid_insights and capacity_monitoring endpoints that already existed
in the generated API client but weren't exposed through the SDK: historical
currents, conductor temperatures, icing, sag and clearance, apparent power,
Heimdall DLRs/AARs, circuit ratings, plus latest apparent power and icing
forecast.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@joakimia
joakimia requested a review from a team as a code owner July 22, 2026 10:51
mHjertaker and others added 7 commits August 5, 2026 11:08
HeimdallApiClient.get_currents imported a grid_insights.get_currents
that was never written, raising ImportError at call time; the lazy
import kept it invisible to ruff and to package import. Add the
wrapper, and a unit test that resolves every lazily-imported wrapper
so this fails in PR CI, where the integration suite does not run.

Also forward two parameters the wrappers silently dropped:
unit_system on get_conductor_temperatures and quantity on
get_heimdall_dlrs, get_heimdall_aars and get_circuit_ratings.

Add integration coverage for all 11 endpoints, skipping on 404 so
per-asset data availability cannot mask a wiring bug.
openapi-python-client formats its output via post_hooks that invoke the
bare `ruff` executable. When ruff is installed but its Scripts directory
is not on PATH, both hooks fail, the generator only warns, and the
result is unformatted code -- a regeneration then shows every file in
the package as modified instead of just the endpoints that changed.

Pin the hooks to `python -m ruff` so they resolve through the same
interpreter that runs the generator, probe the module rather than the
executable, and fail the script if the output is not formatted. Also
fix `-ErrorAction Silently`, which is not a valid value and threw under
`$ErrorActionPreference = "Stop"` when a stale specs/ dir existed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Picks up an optional `since` query parameter the API added to the three
latest-rating endpoints. Purely additive; no wrapper exposes it yet.

Regenerated with the formatting hooks working, so the diff is limited to
the spec change rather than reformatting the whole package.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The API added an optional `since` parameter to the latest Heimdall
DLR/AAR and circuit rating endpoints, bounding how old the returned
value may be. Forward it from HeimdallApiClient through as_zulu, since
the generated code serializes it with isoformat() and the API rejects
the resulting +00:00 offset.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Picks up an optional `since` query parameter on the latest current,
conductor temperature and apparent power endpoints, plus documentation
changes: omitting `since` on the latest icing and sag and clearance
endpoints no longer defaults to 30 minutes ago, it now returns the
latest value per span phase regardless of age.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Forwards `since` on the latest current, conductor temperature and
apparent power endpoints through as_zulu, matching the latest rating
endpoints. Covered by an integration test per endpoint and a unit test
asserting every latest endpoint that the API accepts `since` for exposes
it, so a future regeneration adding the parameter elsewhere is noticed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
test_when_fetching_historical_data.py covered both windowed and latest
endpoints, which are different shapes: one takes a from/to range, the
other a single asset id. Move the latest endpoints to their own file and
lift the shared fixtures and the 404-tolerant assertion helper into
conftest.py.

Also extends latest coverage while the endpoints are grouped: the
forecast endpoints, the facility endpoints, and a generous `since` per
endpoint that distinguishes a working parameter from one the API rejects
outright.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mHjertaker
mHjertaker merged commit e5dc454 into main Aug 5, 2026
4 checks passed
@mHjertaker
mHjertaker deleted the feat/expose-latest-and-historical-endpoint-wrappers branch August 5, 2026 10:08
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.

3 participants