Skip to content

Commit e796e3d

Browse files
committed
fix(backup): strip /api/ prefix from REST paths (double-prefix 404s)
``HomeAssistantClient.httpx_client`` is constructed with ``base_url=f"{self.base_url}/api"`` (rest_client.py:144-145), so ``_request(method, endpoint)`` already routes through ``/api/``. Six backup_manager call sites were passing endpoints with a leading ``/api/`` — causing the actual URLs to become ``/api/api/states/...`` which HA serves as 404. Visible in the b8709ab CI log: GET http://localhost:.../api/api/states/group.e2e_bk_grp_d2489f4b "HTTP/1.1 404 Not Found" Fixed sites: - ``_fetch_group`` — ``states/{eid}`` instead of ``/api/states/{eid}`` - ``_restore_group`` — ``services/group/set`` - ``_restore_calendar_event`` — ``services/calendar/create_event`` - ``_restore_todo_item`` — ``services/todo/add_item`` - ``_fetch_entity_state`` — ``states/{entity_id}`` - ``_restore_entity_state`` — ``states/{entity_id}`` Closes the last real e2e failure (group). category/area passed on the previous run after the ``_backups_for`` sanitization fix — b8709ab was down to just group.
1 parent b8709ab commit e796e3d

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

src/ha_mcp/backup_manager.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ async def _restore_category(client: Any, entity_id: str, config: Any) -> Any:
829829

830830
async def _fetch_group(client: Any, entity_id: str) -> Any:
831831
eid = entity_id if entity_id.startswith("group.") else f"group.{entity_id}"
832-
state = await _rest_get_or_none(client, f"/api/states/{eid}")
832+
state = await _rest_get_or_none(client, f"states/{eid}")
833833
if state is None:
834834
return None
835835
attrs = state.get("attributes", {}) if isinstance(state, dict) else {}
@@ -850,7 +850,7 @@ async def _restore_group(client: Any, entity_id: str, config: Any) -> Any:
850850
service_data["entities"] = config["entities"]
851851
if config.get("icon"):
852852
service_data["icon"] = config["icon"]
853-
return await _rest_post(client, "/api/services/group/set", service_data)
853+
return await _rest_post(client, "services/group/set", service_data)
854854

855855

856856
# Calendar events — calendar.get_events to fetch, calendar.create/update services.
@@ -907,7 +907,7 @@ async def _restore_calendar_event(client: Any, entity_id: str, config: Any) -> A
907907
data = {k: v for k, v in config.items() if k != "calendar_entity_id"}
908908
return await _rest_post(
909909
client,
910-
"/api/services/calendar/create_event",
910+
"services/calendar/create_event",
911911
{"entity_id": cal, **data},
912912
)
913913

@@ -1007,7 +1007,7 @@ async def _restore_todo_item(client: Any, entity_id: str, config: Any) -> Any:
10071007
data = {k: v for k, v in config.items() if k != "todo_entity_id"}
10081008
return await _rest_post(
10091009
client,
1010-
"/api/services/todo/add_item",
1010+
"services/todo/add_item",
10111011
{"entity_id": cal, **data},
10121012
)
10131013

@@ -1016,7 +1016,7 @@ async def _restore_todo_item(client: Any, entity_id: str, config: Any) -> Any:
10161016

10171017

10181018
async def _fetch_entity_state(client: Any, entity_id: str) -> Any:
1019-
return await _rest_get_or_none(client, f"/api/states/{entity_id}")
1019+
return await _rest_get_or_none(client, f"states/{entity_id}")
10201020

10211021

10221022
async def _restore_entity_state(client: Any, entity_id: str, config: Any) -> Any:
@@ -1028,7 +1028,7 @@ async def _restore_entity_state(client: Any, entity_id: str, config: Any) -> Any
10281028
}
10291029
else:
10301030
payload = {"state": str(config)}
1031-
return await _rest_post(client, f"/api/states/{entity_id}", payload)
1031+
return await _rest_post(client, f"states/{entity_id}", payload)
10321032

10331033

10341034
# Integration enable/disable — restore re-applies the disabled flag.

0 commit comments

Comments
 (0)