Abri relay exchange reads as serialise, post, parse, then dispatch on the failure document 🟪

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-03 15:12:44 +00:00
parent 32b56050b0
commit a86607e420

View file

@ -39,51 +39,66 @@ class AbriClient:
("resource_group", RESOURCE_GROUP),
],
)
if isinstance(outcome, AbriRequestRejected):
return outcome
return self._parse_job_logged(outcome)
def _exchange(
self, request_type: str, parameters: List[Tuple[str, str]]
) -> Union[ET.Element, AbriRequestRejected]:
"""Send one relay request; return the success root or the typed rejection.
Shared by all four relay request types: transport failures raise
AbriTransportError, ambiguous bodies raise AbriResponseParseError, and
only a well-formed <success>false</success> body becomes a rejection.
"""
body = serialise_relay_request(
envelope = serialise_relay_request(
request_type=request_type,
parameters=parameters,
username=self._config.username,
password=self._config.password,
)
reply = self._parse_reply(self._post(envelope))
if self._is_failure_document(reply):
return self._parse_rejection(reply)
return reply
def _post(self, envelope: bytes) -> bytes:
try:
response = self._session.post(self._config.endpoint_url, data=body)
response = self._session.post(self._config.endpoint_url, data=envelope)
response.raise_for_status()
except requests.RequestException as error:
raise AbriTransportError(str(error)) from error
return response.content
@staticmethod
def _parse_reply(body: bytes) -> ET.Element:
try:
root = ET.fromstring(response.content)
return ET.fromstring(body)
except ET.ParseError as error:
raise AbriResponseParseError(str(error)) from error
if root.tag == "response":
return self._parse_rejection(root)
return root
@staticmethod
def _is_failure_document(reply: ET.Element) -> bool:
return reply.tag == "response"
@staticmethod
def _parse_job_logged(root: ET.Element) -> JobLogged:
job_logged = root.find("Jobs/Job_logged")
if job_logged is None:
raise AbriResponseParseError(
"Job_logged element missing from relay response"
)
job_no = job_logged.get("job_no")
logged_info = job_logged.get("logged_info")
if job_no is None or logged_info is None:
raise AbriResponseParseError(
"Job_logged element missing job_no or logged_info"
)
return JobLogged(job_no=job_no, logged_info=logged_info)
@staticmethod
@ -91,6 +106,8 @@ class AbriClient:
success = root.findtext("success")
code = root.findtext("code")
message = root.findtext("message")
if success != "false" or code is None or message is None:
raise AbriResponseParseError("malformed relay failure response")
return AbriRequestRejected(code=code, message=message)