From 40067536206efadd05a2538fc133c258db28d1e7 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 8 Jun 2026 20:58:22 +0000 Subject: [PATCH] fix(scripts): authenticate the EPC client with OPEN_EPC_API_TOKEN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new gov EPC API (api.get-energy-performance-data..., Bearer auth) returns 403 "Bad authentication header" with EPC_AUTH_TOKEN but 200 with OPEN_EPC_API_TOKEN — the token name is misleading (it is the Bearer token for the new API, not the open-data API). Verified live against /api/domestic/search. Unblocks the live EPC fetch in run_modelling_e2e. Co-Authored-By: Claude Opus 4.8 --- scripts/run_modelling_e2e.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/run_modelling_e2e.py b/scripts/run_modelling_e2e.py index 80a53db6..e38fdb63 100644 --- a/scripts/run_modelling_e2e.py +++ b/scripts/run_modelling_e2e.py @@ -20,7 +20,8 @@ band); without it the run synthesises an Increasing-EPC-to-``--goal`` Scenario. (mirroring the legacy `inclusions`) — e.g. only HHRSH + Solar PV. Config: loads `backend/.env` for the DB creds (`DB_*`), the EPC API token -(`EPC_AUTH_TOKEN`), the Google Solar key (`GOOGLE_SOLAR_API_KEY`) and the S3 +(`OPEN_EPC_API_TOKEN` — the Bearer token for the new gov API), the Google Solar +key (`GOOGLE_SOLAR_API_KEY`) and the S3 reference bucket (`DATA_BUCKET`) — the agent never sees the secrets. AWS creds come from the ambient `~/.aws` profile. Run from the worktree root: @@ -280,7 +281,10 @@ def main() -> None: parser.error("--persist requires --scenario-id and --portfolio-id") _load_env(_ENV_PATH) - epc_client = EpcClientService(os.environ["EPC_AUTH_TOKEN"]) + # The new gov EPC API (Bearer) authenticates with OPEN_EPC_API_TOKEN — the + # name is misleading; EPC_AUTH_TOKEN is dead (403). Verified against the + # /api/domestic/search endpoint. + epc_client = EpcClientService(os.environ["OPEN_EPC_API_TOKEN"]) geospatial = GeospatialS3Repository(_s3_parquet_reader(os.environ["DATA_BUCKET"])) solar_client = GoogleSolarApiClient(os.environ["GOOGLE_SOLAR_API_KEY"]) engine = _engine()