@classmethod
def from_dict(cls, key: str, data: dict[str, Any]) -> SyncRecord:
if key == '':
message = 'SyncRecord key must be a non-empty string'
raise RecordFieldError(message)
record_data = data.get('data', {})
record_timestamps = data.get('timestamps', {})
record_received_at = data.get('received_at', 0)
record_sequence = data.get('sequence', 0)
record_origin_node = data.get('origin_node', '')
if not isinstance(record_data, dict):
message = (
f"Record {key!r}: 'data' must be a dict, "
f'got {type(record_data).__name__}'
)
raise RecordFieldError(message)
if not isinstance(record_timestamps, dict):
message = (
f"Record {key!r}: 'timestamps' must be a "
f'dict, got {type(record_timestamps).__name__}'
)
raise RecordFieldError(message)
record_received_at = _coerce_int(
record_received_at,
"'received_at'",
key,
)
if record_received_at < 0:
message = (
f"Record {key!r}: 'received_at' must be "
f'non-negative, got {record_received_at}'
)
raise RecordFieldError(message)
record_sequence = _coerce_int(
record_sequence,
"'sequence'",
key,
)
if record_sequence < 0:
message = (
f"Record {key!r}: 'sequence' must be "
f'non-negative, got {record_sequence}'
)
raise RecordFieldError(message)
if not isinstance(record_origin_node, str):
message = (
f"Record {key!r}: 'origin_node' must be a string, "
f'got {type(record_origin_node).__name__}'
)
raise RecordFieldError(message)
sanitized_timestamps: dict[str, int] = {}
for timestamp_key, timestamp_value in record_timestamps.items():
if not isinstance(timestamp_key, str):
message = (
f'Record {key!r}: timestamp key '
f'{timestamp_key!r} must be a string'
)
raise RecordFieldError(message)
coerced = _coerce_int(
timestamp_value,
f'timestamp for {timestamp_key!r}',
key,
)
if coerced < 0:
message = (
f'Record {key!r}: timestamp for '
f'{timestamp_key!r} must be non-negative, '
f'got {coerced}'
)
raise RecordFieldError(message)
sanitized_timestamps[timestamp_key] = coerced
return cls(
key=key,
data=record_data,
timestamps=sanitized_timestamps,
sequence=record_sequence,
origin_node=record_origin_node,
received_at=record_received_at,
)