Python’s uuid module generates RFC 4122 Universally Unique Identifiers. import uuid. uuid4: uuid.uuid4() — random UUID (most common). uuid1: uuid.uuid1() — time + MAC address (sortable, leaks host info). uuid3: uuid.uuid3(namespace, name) — MD5-based deterministic. uuid5: uuid.uuid5(namespace, name) — SHA-1-based deterministic (prefer over uuid3). UUID: u = uuid.UUID("550e8400-e29b-41d4-a716-446655440000") — parse from string. str: str(u) → “550e8400-e29b-41d4-a716-446655440000”. hex: u.hex → 32-char lowercase hex, no dashes. bytes: u.bytes → 16 raw bytes. int: u.int → 128-bit integer. urn: u.urn → “urn:uuid:550e8400-…”. version: u.version → 4. variant: u.variant. NAMESPACE_DNS / NAMESPACE_URL / NAMESPACE_OID / NAMESPACE_X500: standard namespace UUIDs for uuid3/uuid5. uuid.UUID(bytes=b"\x00"*16) — from bytes. uuid.UUID(int=0) — from int. Comparison: UUIDs support ==, <, >, sortable (UUID version 1 sorts by time). UUID(hex=“550e8400e29b41d4a716446655440000”). Claude Code generates entity IDs, idempotency keys, distributed trace IDs, and deterministic test fixtures.
CLAUDE.md for uuid
## uuid Stack
- Stdlib: import uuid
- Random: uid = uuid.uuid4() — 122 bits of randomness
- String: str(uid) — "8fa3b..."-format
- Hex: uid.hex — no dashes, 32 chars
- Parse: uuid.UUID("550e8400-e29b-41d4-a716-446655440000")
- Deterministic: uuid.uuid5(uuid.NAMESPACE_URL, url_string)
- Validate: uuid.UUID(s) in try/except ValueError
uuid Identity Pipeline
# app/idutil.py — uuid4, uuid5, short IDs, deterministic, validation
from __future__ import annotations
import base64
import hashlib
import re
import uuid
from dataclasses import dataclass
from typing import Any
# ─────────────────────────────────────────────────────────────────────────────
# 1. Generation helpers
# ─────────────────────────────────────────────────────────────────────────────
def new_id() -> str:
"""
Generate a new random UUID4 as a lowercase hex string (no dashes).
Example:
id = new_id() # "e3d4f5a6b7c8d9e0f1a2b3c4d5e6f7a8"
"""
return uuid.uuid4().hex
def new_uuid() -> uuid.UUID:
"""Generate a new UUID4 object."""
return uuid.uuid4()
def new_prefixed_id(prefix: str) -> str:
"""
Generate a prefixed ID similar to Stripe/Clerk resource IDs.
Example:
user_id = new_prefixed_id("usr") # "usr_e3d4f5a6b7c8d9e0..."
order_id = new_prefixed_id("order") # "order_f1a2b3c4d5e6f7a8..."
"""
return f"{prefix}_{uuid.uuid4().hex}"
def deterministic_id(namespace: str, name: str) -> str:
"""
Generate a deterministic UUID5 from a namespace and name string.
Same inputs always produce the same ID.
Example:
id1 = deterministic_id("users", "[email protected]")
id2 = deterministic_id("users", "[email protected]")
assert id1 == id2
"""
ns = uuid.uuid5(uuid.NAMESPACE_URL, f"https://id.example.com/{namespace}")
return uuid.uuid5(ns, name).hex
def url_to_id(url: str) -> str:
"""
Generate a stable deterministic ID from a URL using UUID5.
Example:
page_id = url_to_id("https://example.com/posts/hello-world")
"""
return uuid.uuid5(uuid.NAMESPACE_URL, url).hex
def dns_to_id(hostname: str) -> str:
"""
Generate a stable deterministic ID from a DNS name using UUID5.
Example:
host_id = dns_to_id("api.example.com")
"""
return uuid.uuid5(uuid.NAMESPACE_DNS, hostname).hex
# ─────────────────────────────────────────────────────────────────────────────
# 2. Compact representations
# ─────────────────────────────────────────────────────────────────────────────
def to_short_id(uid: uuid.UUID) -> str:
"""
Encode a UUID as a URL-safe base64 string (22 chars, no padding).
Example:
uid = uuid.uuid4()
short = to_short_id(uid) # "VhvASuKbQdSqcUZmVUQAAA"
back = from_short_id(short)
assert back == uid
"""
return base64.urlsafe_b64encode(uid.bytes).rstrip(b"=").decode()
def from_short_id(short: str) -> uuid.UUID:
"""
Decode a URL-safe base64 short ID back to a UUID.
Example:
uid = from_short_id("VhvASuKbQdSqcUZmVUQAAA")
"""
padded = short + "==" [:(2 - len(short) % 2) % 2]
return uuid.UUID(bytes=base64.urlsafe_b64decode(padded))
def to_compact(uid: uuid.UUID) -> str:
"""
Return UUID as a 32-char lowercase hex string (no dashes).
Example:
compact = to_compact(uuid.uuid4()) # "e3d4f5a6b7c8d9e0f1a2b3c4d5e6f7a8"
"""
return uid.hex
def from_compact(hex_str: str) -> uuid.UUID:
"""
Parse a 32-char hex string back to a UUID.
Example:
uid = from_compact("e3d4f5a6b7c8d9e0f1a2b3c4d5e6f7a8")
"""
return uuid.UUID(hex=hex_str)
# ─────────────────────────────────────────────────────────────────────────────
# 3. Validation and parsing
# ─────────────────────────────────────────────────────────────────────────────
_UUID_RE = re.compile(
r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
re.IGNORECASE,
)
def is_valid_uuid(value: str) -> bool:
"""
Return True if value is a valid UUID string in canonical form.
Example:
is_valid_uuid("550e8400-e29b-41d4-a716-446655440000") # True
is_valid_uuid("not-a-uuid") # False
"""
try:
uuid.UUID(str(value))
return True
except (ValueError, AttributeError):
return False
def parse_uuid(value: str, version: int | None = None) -> uuid.UUID | None:
"""
Parse a UUID string; return None if invalid.
Optionally check that the parsed UUID has the expected version.
Example:
uid = parse_uuid("550e8400-e29b-41d4-a716-446655440000")
uid4 = parse_uuid(some_str, version=4)
"""
try:
u = uuid.UUID(str(value))
if version is not None and u.version != version:
return None
return u
except (ValueError, AttributeError):
return None
def must_parse_uuid(value: str) -> uuid.UUID:
"""
Parse a UUID string; raise ValueError with a descriptive message if invalid.
Example:
uid = must_parse_uuid(request.headers["X-IdempotencyKey"])
"""
try:
return uuid.UUID(str(value))
except (ValueError, AttributeError) as exc:
raise ValueError(f"Invalid UUID: {value!r}") from exc
def uuid_version(value: str) -> int | None:
"""
Return the version of a UUID string (1–5) or None if invalid.
Example:
uuid_version("550e8400-e29b-41d4-a716-446655440000") # 4
"""
u = parse_uuid(value)
return u.version if u else None
# ─────────────────────────────────────────────────────────────────────────────
# 4. Idempotency and entity ID patterns
# ─────────────────────────────────────────────────────────────────────────────
@dataclass
class Entity:
"""
Base entity with a UUID4 primary key.
Example:
user = Entity.new()
print(user.id) # UUID object
print(user.id_str) # "e3d4f5a6-..."
print(user.id_hex) # "e3d4f5a6b7c8..."
"""
id: uuid.UUID
@classmethod
def new(cls) -> "Entity":
return cls(id=uuid.uuid4())
@property
def id_str(self) -> str:
return str(self.id)
@property
def id_hex(self) -> str:
return self.id.hex
@property
def id_short(self) -> str:
return to_short_id(self.id)
def idempotency_key(
operation: str,
*args: Any,
namespace: str = "ops",
) -> str:
"""
Generate a deterministic idempotency key for an operation.
Example:
key = idempotency_key("charge", user_id, order_id, amount_cents)
# Same inputs → same key → safe to retry
"""
payload = "|".join(str(a) for a in (operation, *args))
return deterministic_id(namespace, payload)
def content_id(data: bytes | str) -> str:
"""
Generate a deterministic UUID5-based content ID from bytes/string content.
Useful for deduplication.
Example:
cid = content_id(file_bytes)
"""
if isinstance(data, str):
data = data.encode()
digest = hashlib.sha1(data).hexdigest()
return uuid.uuid5(uuid.NAMESPACE_OID, digest).hex
# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
print("=== uuid demo ===")
print("\n--- generation ---")
uid4 = uuid.uuid4()
uid1 = uuid.uuid1()
print(f" uuid4: {uid4}")
print(f" uuid1: {uid1}")
print(f" new_id(): {new_id()!r}")
print("\n--- prefixed IDs ---")
for prefix in ["usr", "order", "pay"]:
print(f" {new_prefixed_id(prefix)!r}")
print("\n--- deterministic (uuid5) ---")
for _ in range(3):
d = deterministic_id("users", "[email protected]")
print(f" deterministic_id('users', 'alice'): {d!r}")
print(f" url_to_id: {url_to_id('https://example.com/post/hello-world')!r}")
print(f" dns_to_id: {dns_to_id('api.example.com')!r}")
print("\n--- compact / short representations ---")
u = uuid.uuid4()
short = to_short_id(u)
compact = to_compact(u)
print(f" full: {str(u)!r} ({len(str(u))} chars)")
print(f" short: {short!r} ({len(short)} chars)")
print(f" compact: {compact!r} ({len(compact)} chars)")
print(f" roundtrip short: {from_short_id(short) == u}")
print(f" roundtrip compact: {from_compact(compact) == u}")
print("\n--- validation ---")
for s in [str(u), uid4.hex, "not-a-uuid", "550e8400-e29b-41d4-a716-446655440000", ""]:
print(f" {s!r[:40]:42s}: valid={is_valid_uuid(s)!r} version={uuid_version(s)!r}")
print("\n--- Entity ---")
e = Entity.new()
print(f" id: {e.id_str}")
print(f" id_hex: {e.id_hex}")
print(f" id_short: {e.id_short}")
print("\n--- idempotency_key ---")
for _ in range(3):
key = idempotency_key("charge", "user_123", "order_456", 4999)
print(f" key: {key!r}")
print("\n--- content_id deduplication ---")
data = b"hello, world"
print(f" content_id same: {content_id(data) == content_id(data)}")
print(f" content_id differs: {content_id(data) != content_id(b'different')}")
print("\n=== done ===")
For the ulid-py / python-ulid alternative — ULID (Universally Unique Lexicographically Sortable Identifier) encodes a 48-bit millisecond timestamp followed by 80 bits of randomness in a 26-char Crockford base32 string; ULIDs sort chronologically as strings and are human-readable in logs; stdlib uuid.uuid4() is random-only with no time component — use ULID for database primary keys where insert-order locality matters (B-tree performance) and human-readable chronological sorting is useful, uuid4 for pure randomness with maximum collision resistance and database-agnostic string type. For the shortuuid alternative — shortuuid (PyPI) encodes UUID4 bytes in a shorter alphabet (e.g., 22-char base57 without ambiguous characters like 0/O/I/l) for human-transcribable short IDs; stdlib uuid produces 36-char canonical or 32-char hex; the to_short_id() function above achieves 22 chars via base64 — use shortuuid for user-facing IDs appearing in URLs, invoices, or support tickets where brevity and readability matter, stdlib uuid for internal system identifiers where format portability is required. The Claude Skills 360 bundle includes uuid skill sets covering new_id()/new_uuid()/new_prefixed_id() generation helpers, deterministic_id()/url_to_id()/dns_to_id() UUID5 deterministic IDs, to_short_id()/from_short_id()/to_compact()/from_compact() encoding utilities, is_valid_uuid()/parse_uuid()/must_parse_uuid()/uuid_version() validation, and Entity base class with idempotency_key()/content_id() application patterns. Start with the free tier to try unique identifier generation and uuid pipeline code generation.