identifiers.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. from __future__ import annotations
  2. import secrets
  3. import time
  4. import uuid
  5. from typing import Any, MutableMapping
  6. def new_governance_uid() -> str:
  7. """Return an RFC 9562 UUIDv7-compatible identifier."""
  8. timestamp_ms = int(time.time_ns() // 1_000_000) & ((1 << 48) - 1)
  9. random_a = secrets.randbits(12)
  10. random_b = secrets.randbits(62)
  11. value = (
  12. (timestamp_ms << 80)
  13. | (0x7 << 76)
  14. | (random_a << 64)
  15. | (0b10 << 62)
  16. | random_b
  17. )
  18. return str(uuid.UUID(int=value))
  19. def ensure_governance_uid(properties: MutableMapping[str, Any]) -> str:
  20. """Attach a UUIDv7 to mutable node properties and preserve it on retries."""
  21. existing = properties.get("uid")
  22. if existing:
  23. try:
  24. parsed = uuid.UUID(str(existing))
  25. except (ValueError, AttributeError, TypeError) as exc:
  26. raise ValueError("governance uid must be a valid UUIDv7") from exc
  27. if parsed.version != 7 or parsed.variant != uuid.RFC_4122:
  28. raise ValueError("governance uid must be a valid UUIDv7")
  29. value = str(parsed)
  30. else:
  31. value = new_governance_uid()
  32. properties["uid"] = value
  33. return value