arm-core/api/src/contract/message.py
2026-10-03 23:01:23 +04:00

64 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Конверт сообщения на `recognition.result`: `recognition-result-message.schema.json` v1.0.
`processing` — ack «взял в работу» (до чтения файла из S3); `done | needs_check | error` — итог.
Условная обязательность — буквально из `allOf` схемы: для `done | needs_check` обязательны `result_s3` и
`result_schema_version`; для `error` — `error`. Других правил нет (например, `error` при `done` схема не запрещает).
"""
from enum import StrEnum
from typing import Annotated, Self
from pydantic import Field, model_validator
from src.contract.common import (
ContractModel,
ContractUUID,
LaxErrorCode,
Metrics,
OptionalNotNull,
ResultSchemaVersion,
S3Ref,
SchemaVersion,
ServiceInfo,
)
class MessageStatus(StrEnum):
PROCESSING = "processing"
DONE = "done"
NEEDS_CHECK = "needs_check"
ERROR = "error"
LaxMessageStatus = Annotated[MessageStatus, Field(strict=False)]
class MessageError(ContractModel):
"""`error {code, message}` конверта: оба поля обязательны."""
code: LaxErrorCode
message: str
class RecognitionResultMessage(ContractModel):
schema_version: SchemaVersion
job_id: ContractUUID # recognition_job.id
file_id: ContractUUID # stored_file.id
status: LaxMessageStatus
service: ServiceInfo
result_s3: OptionalNotNull[S3Ref] = None # results/{file_id}/{job_id}/result.json
result_schema_version: OptionalNotNull[ResultSchemaVersion] = None # schema_version файла результата
error: OptionalNotNull[MessageError] = None
raw_s3_key: str | None = None # scan-gateway: raw/{job_id}.json; в БД не регистрируется
metrics: OptionalNotNull[Metrics] = None
@model_validator(mode="after")
def _check_status_requirements(self) -> Self:
if self.status in (MessageStatus.DONE, MessageStatus.NEEDS_CHECK):
missing = [name for name in ("result_s3", "result_schema_version") if getattr(self, name) is None]
if missing:
raise ValueError(f"при status = {self.status.value} обязательны поля: {', '.join(missing)}")
elif self.status is MessageStatus.ERROR and self.error is None:
raise ValueError("при status = error обязательно поле error")
return self