feat(downloader): hoist derive_download_window, extract_entsoe_hourly_forecast, download_side_tables#384
Merged
Conversation
…orecast, download_side_tables Hoist three small, pure/safe-compatible utilities out of the bart26l-vorlesung team_4 four-zone submission script into the certified downloader, where they can be tested and documented: - derive_download_window(now, *, train_years, start_margin_days=45, data_end=None) -> (start_dl, end_dl): derives the ENTSO-E download window from a training horizon. Requires a tz-aware `now`; rejects bool/non-positive train_years and malformed data_end. - extract_entsoe_hourly_forecast(interim, *, column="Forecasted Load"): resamples an interim frame's day-ahead forecast column to a clean hourly series; raises on missing column / non-DatetimeIndex / all-NaN. - download_side_tables(...): one call to refresh the renewable-forecast and day-ahead-price side tables. Fail-loud by default (on_provider_failure="raise"); "skip" is opt-in, logged degradation (operator policy). All three use only pandas + stdlib + existing downloader functions — no spotforecast2 import, no __init__ change (registered in _quarto.yml only). The warn-and-continue / fallback policy stays operator-side per the established mechanism-vs-policy boundary. Tests: new tests/test_downloader_entsoe_utils.py (pure functions) and extended tests/test_downloader_entsoe_side_tables.py (download_side_tables). Fast suite green, coverage 73.8% (ratchet 68). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment on lines
+240
to
+245
| result = download_side_tables( | ||
| api_key="x", | ||
| start="202301010000", | ||
| end="202301050000", | ||
| force=True, | ||
| ) |
Comment on lines
+276
to
+282
| result = download_side_tables( | ||
| api_key="x", | ||
| start="202301010000", | ||
| end="202301050000", | ||
| force=True, | ||
| on_provider_failure="skip", | ||
| ) |
Comment on lines
+302
to
+308
| result = download_side_tables( | ||
| api_key="x", | ||
| start="202301010000", | ||
| end="202301050000", | ||
| force=True, | ||
| on_provider_failure="skip", | ||
| ) |
| import pandas as pd | ||
| import pytest | ||
|
|
||
| import spotforecast2_safe.downloader.entsoe as _entsoe_mod |
This was referenced Jun 14, 2026
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
Hoist three small, pure/safe-compatible utilities out of the
bart26l-vorlesungteam_4 four-zone submission script into the certified downloader (downloader/entsoe.py), so they can be tested and documented in one place:derive_download_window(now, *, train_years, start_margin_days=45, data_end=None) -> (start_dl, end_dl)— derives the ENTSO-E download window from a training horizon. Requires a tz-awarenow; rejects bool/non-positivetrain_yearsand malformeddata_end.extract_entsoe_hourly_forecast(interim, *, column="Forecasted Load")— resamples an interim frame's day-ahead forecast column to a clean hourly series; raises on missing column / non-DatetimeIndex/ all-NaN.download_side_tables(...)— one call to refresh the renewable-forecast and day-ahead-price side tables. Fail-loud by default (on_provider_failure="raise");"skip"is opt-in, logged degradation (operator policy).Constraints respected
spotforecast2import (one-way fail-safe boundary preserved).__init__.pychange — downloader functions are imported by full path; the three symbols are registered in_quarto.ymlonly.STRIDE
No threat-model table update required: the two pure functions cross no boundary, and
download_side_tablesopens no new endpoint (it orchestrates the already-coveredquery_wind_and_solar_forecast/query_day_ahead_prices, inheriting their bounded-retry countermeasure). The certified default is unchanged ("raise");"skip"is opt-in and logged.Tests / docs
tests/test_downloader_entsoe_utils.py(pure functions, incl. fail-safe paths).tests/test_downloader_entsoe_side_tables.py(raise/skip/invalid/country-routing fordownload_side_tables)._quarto.yml.🤖 Generated with Claude Code