The uuid module generates universally unique identifiers—128-bit values that are practically guaranteed to be unique across time and space.
The Four UUID Types
import uuid
# UUID1: based on host MAC + timestamp
u1 = uuid.uuid1()
# Reveals when/where it was created
# UUID3: MD5 hash of namespace + name
u3 = uuid.uuid3(uuid.NAMESPACE_DNS, 'example.com')
# Deterministic: same input = same UUID
# UUID4: random
u4 = uuid.uuid4()
# Most common choice
# UUID5: SHA-1 hash of namespace + name
u5 = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
# Like UUID3 but with SHA-1UUID4: The Default Choice
For most applications, use uuid4():
import uuid
# Generate random UUID
user_id = uuid.uuid4()
print(user_id)
# 550e8400-e29b-41d4-a716-446655440000
# As string
print(str(user_id))
# As 32-char hex (no dashes)
print(user_id.hex)
# 550e8400e29b41d4a716446655440000
# As bytes
print(user_id.bytes)
# b'U\x0e\x84\x00\xe2\x9bA\xd4\xa7\x16DfUD\x00\x00'
# As integer
print(user_id.int)UUID5: Deterministic IDs
When you need the same UUID for the same input:
import uuid
# Built-in namespaces
ns_dns = uuid.NAMESPACE_DNS # For domain names
ns_url = uuid.NAMESPACE_URL # For URLs
ns_oid = uuid.NAMESPACE_OID # For ISO OIDs
ns_x500 = uuid.NAMESPACE_X500 # For X.500 DNs
# Same input always gives same UUID
id1 = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
id2 = uuid.uuid5(uuid.NAMESPACE_DNS, 'example.com')
assert id1 == id2
# Different namespace or name = different UUID
id3 = uuid.uuid5(uuid.NAMESPACE_URL, 'example.com')
assert id1 != id3Use cases:
- Idempotent imports (same source data = same ID)
- Derived IDs (user ID + "profile" = profile ID)
- Content addressing
UUID1: Time-Based
Contains timestamp and MAC address:
import uuid
u = uuid.uuid1()
# Extract timestamp (100-ns intervals since Oct 1582)
print(u.time)
# Extract node (usually MAC address)
print(hex(u.node))Privacy concern: Reveals creation time and host identity.
Use when you need:
- Sortable IDs (rough time ordering)
- Audit trail (know when/where created)
Parsing UUIDs
import uuid
# From string
u = uuid.UUID('550e8400-e29b-41d4-a716-446655440000')
# From hex (no dashes)
u = uuid.UUID('550e8400e29b41d4a716446655440000')
# From bytes
u = uuid.UUID(bytes=b'U\x0e\x84\x00\xe2\x9bA\xd4\xa7\x16DfUD\x00\x00')
# From int
u = uuid.UUID(int=113059749145936325402354257176981405696)UUID Properties
u = uuid.uuid4()
u.hex # 32-char hex string
u.bytes # 16 bytes
u.int # 128-bit integer
u.urn # 'urn:uuid:...'
u.version # 4 for uuid4
u.variant # uuid.RFC_4122Common Patterns
Database Primary Keys
from dataclasses import dataclass, field
import uuid
@dataclass
class User:
id: uuid.UUID = field(default_factory=uuid.uuid4)
name: str = ""
email: str = ""
user = User(name="Alice", email="alice@example.com")
print(user.id) # Auto-generated UUIDURL-Safe Short IDs
import uuid
import base64
def short_uuid() -> str:
"""Generate a URL-safe 22-char ID."""
u = uuid.uuid4()
return base64.urlsafe_b64encode(u.bytes).rstrip(b'=').decode()
print(short_uuid()) # 'VQ6EAOKbQdSnFkRmVUQAAA'Derived IDs
import uuid
def derived_id(parent_id: uuid.UUID, suffix: str) -> uuid.UUID:
"""Generate deterministic child ID."""
return uuid.uuid5(parent_id, suffix)
user_id = uuid.uuid4()
profile_id = derived_id(user_id, 'profile')
settings_id = derived_id(user_id, 'settings')When to Use What
| Type | When to Use |
|---|---|
| UUID4 | Default choice. Random, no information leak. |
| UUID5 | Deterministic mapping from input to ID. |
| UUID1 | Need timestamp/sorting, accept privacy tradeoff. |
| UUID3 | Like UUID5 but legacy (MD5). |
Comparison with Alternatives
| Format | Length | Sortable | Info Leak |
|---|---|---|---|
| UUID4 | 36 chars | No | None |
| UUID1 | 36 chars | Partial | Time + MAC |
| ULID | 26 chars | Yes | Time |
| nanoid | 21 chars | No | None |
| Auto-increment | Variable | Yes | Count |
UUIDs are verbose but universally understood and supported by every database.
Quick Reference
import uuid
# Generate
uuid.uuid4() # Random (most common)
uuid.uuid5(ns, name) # Deterministic from input
uuid.uuid1() # Time + MAC based
# Parse
uuid.UUID('string') # From string
uuid.UUID(hex='...') # From hex
uuid.UUID(bytes=b'...') # From bytes
# Properties
u.hex # Without dashes
u.bytes # Raw bytes
u.int # Integer
str(u) # With dashesStart with uuid4(). Reach for uuid5() when you need determinism.
React to this post: