Files
kontextual-engine/src/kontextual_engine/core/idempotency.py

49 lines
1.4 KiB
Python

"""Idempotency records for mutation safety."""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from typing import Any
from .primitives import compact_dict, utc_now
class IdempotencyStatus(str, Enum):
COMPLETED = "completed"
FAILED = "failed"
@dataclass(frozen=True)
class IdempotencyRecord:
key: str
operation: str
request_hash: str
result_refs: dict[str, Any]
status: IdempotencyStatus = IdempotencyStatus.COMPLETED
created_at: str = field(default_factory=lambda: utc_now().isoformat())
def to_dict(self) -> dict[str, Any]:
return compact_dict(
{
"key": self.key,
"operation": self.operation,
"request_hash": self.request_hash,
"result_refs": dict(self.result_refs),
"status": self.status.value,
"created_at": self.created_at,
}
)
@classmethod
def from_dict(cls, data: dict[str, Any]) -> "IdempotencyRecord":
return cls(
key=data["key"],
operation=data["operation"],
request_hash=data["request_hash"],
result_refs=dict(data.get("result_refs", {})),
status=IdempotencyStatus(data.get("status", IdempotencyStatus.COMPLETED.value)),
created_at=data["created_at"],
)