feat(python): expose historical and latest endpoint wrappers - #143
Merged
mHjertaker merged 8 commits intoAug 5, 2026
Merged
Conversation
…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>
sarahsa
approved these changes
Jul 22, 2026
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
deleted the
feat/expose-latest-and-historical-endpoint-wrappers
branch
August 5, 2026 10:08
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.
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
get_currents,get_conductor_temperatures,get_icing,get_sag_and_clearance,get_apparent_power,get_heimdall_dlrs,get_heimdall_aars,get_circuit_ratingsget_latest_apparent_power,get_icing_forecastFixes
get_currentsraisedImportErrorat call time — the client method imported a wrapper that was never written. The import is function-local, so linting and package import stayed green.datetime.isoformat()always emits a+00:00offset. Normalized viaas_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.unit_systemonget_conductor_temperatures,quantityon the three rating endpoints, andsinceon the latest endpoints that accept it.Generator
openapi-python-clientformats its output via post-hooks that call the bareruffexecutable, which silently no-ops when ruff is not onPATH— leaving generated code unformatted and turning a 3-file change into a 54-file diff. The hooks now run throughpython -m ruff, and unformatted output failsgenerate-module-client.ps1rather than reaching a commit. Both modules are regenerated with that in place.Tests
tests/integration/— windowed and latest endpoints in separate files, coveringunit_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 coversas_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 passedpoetry run pytest -m integration— 38 passed, 13 skippedpoetry buildAI usage