generated from coulomb/repo-seed
44 lines
1.1 KiB
Python
44 lines
1.1 KiB
Python
"""Small deterministic primitives used by the domain core."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import uuid
|
|
from datetime import datetime, timezone
|
|
from typing import Any
|
|
|
|
|
|
def utc_now() -> datetime:
|
|
return datetime.now(timezone.utc)
|
|
|
|
|
|
def new_id(prefix: str) -> str:
|
|
return f"{prefix}_{uuid.uuid4().hex}"
|
|
|
|
|
|
def stable_json_dumps(value: Any) -> str:
|
|
return json.dumps(value, sort_keys=True, separators=(",", ":"), default=str)
|
|
|
|
|
|
def content_digest(content: str | bytes) -> str:
|
|
data = content.encode("utf-8") if isinstance(content, str) else content
|
|
return "sha256:" + hashlib.sha256(data).hexdigest()
|
|
|
|
|
|
def mapping_digest(value: Any) -> str:
|
|
return content_digest(stable_json_dumps(value))
|
|
|
|
|
|
def compact_dict(data: dict[str, Any]) -> dict[str, Any]:
|
|
return {key: value for key, value in data.items() if value not in (None, {}, [])}
|
|
|
|
|
|
def datetime_to_str(value: datetime | None) -> str | None:
|
|
return value.isoformat() if value else None
|
|
|
|
|
|
def datetime_from_str(value: str | None) -> datetime | None:
|
|
return datetime.fromisoformat(value) if value else None
|
|
|