feat: update endpoint to support the new UI request type

The UI now sends a Program as defined in our schemas.

ref: N25B-200
This commit is contained in:
Twirre Meulenbelt
2025-11-12 16:30:42 +01:00
parent 5376b3bb4c
commit 858a554c78

View File

@@ -1,10 +1,10 @@
import json
import logging
from fastapi import APIRouter, HTTPException, Request
from pydantic import ValidationError
from control_backend.schemas.message import Message
from control_backend.schemas.program import Phase
from control_backend.schemas.program import Program
logger = logging.getLogger(__name__)
router = APIRouter()
@@ -16,37 +16,20 @@ async def receive_message(program: Message, request: Request):
Receives a BehaviorProgram as a stringified JSON list inside `message`.
Converts it into real Phase objects.
"""
logger.info("Received raw program: ")
logger.debug("%s", program)
logger.debug("Received raw program: %s", program)
raw_str = program.message # This is the JSON string
# Convert Json into dict.
# Validate program
try:
program_list = json.loads(raw_str)
except json.JSONDecodeError as e:
logger.error("Failed to decode program JSON: %s", e)
raise HTTPException(status_code=400, detail="Undecodeable Json string") from None
# Validate Phases
try:
phases: list[Phase] = [Phase(**phase) for phase in program_list]
except Exception as e:
logger.error("❌ Failed to convert to Phase objects: %s", e)
raise HTTPException(status_code=400, detail="Non-Phase String") from None
logger.info(f"Succesfully recieved {len(phases)} Phase(s).")
for p in phases:
logger.info(
f"Phase {p.id}: "
f"{len(p.phaseData.norms)} norms, "
f"{len(p.phaseData.goals)} goals, "
f"{len(p.phaseData.triggers) if hasattr(p.phaseData, 'triggers') else 0} triggers"
)
program = Program.model_validate_json(raw_str)
except ValidationError as e:
logger.error("Failed to validate program JSON: %s", e)
raise HTTPException(status_code=400, detail="Not a valid program") from None
# send away
topic = b"program"
body = json.dumps([p.model_dump() for p in phases]).encode("utf-8")
body = program.model_dump_json().encode()
pub_socket = request.app.state.endpoints_pub_socket
await pub_socket.send_multipart([topic, body])
return {"status": "Program parsed", "phase_count": len(phases)}
return {"status": "Program parsed"}