Scanning database...
Tools
Articles

No matches found for ""

View All Results
Home Dev Lab python
Developer Lab

UUID in Python

Production-ready implementation guide with CSPRNG-backed code snippets.



Generate UUID in Python

Python ships a uuid module in its standard library — no pip install, no dependencies. uuid.uuid4() gives you a CSPRNG-backed v4 UUID in one line.

Quick Reference

Function Version Sortable Use Case
uuid.uuid4() v4 No General purpose — session IDs, API keys, record IDs
uuid.uuid1() v1 Yes Legacy systems, Cassandra timeuuid
uuid.uuid5() v5 No Deterministic — same input always gives same UUID
uuid.UUID(str) any Parse and validate an existing UUID string

Primary Implementation

Production Ready
python snippet
import uuid

# UUID v4 — random, CSPRNG-backed, zero dependencies
id = uuid.uuid4()
print(id)
# → f47ac10b-58cc-4372-a567-0e02b2c3d479

# As a plain string
id_str = str(uuid.uuid4())

# As a 32-char hex string (no hyphens)
id_hex = uuid.uuid4().hex
# → f47ac10b58cc4372a5670e02b2c3d479

# As bytes (16 bytes)
id_bytes = uuid.uuid4().bytes

# Generate multiple
ids = [str(uuid.uuid4()) for _ in range(5)]

# Parse and validate an existing UUID string
try:
    parsed = uuid.UUID("f47ac10b-58cc-4372-a567-0e02b2c3d479")
    print(parsed.version)  # → 4
except ValueError:
    print("Invalid UUID")

All UUID Versions

UUID v4 — Random (recommended default)

python snippet
import uuid
# 122 bits of randomness — use for anything that just needs a unique ID
id = uuid.uuid4()
print(str(id))  # → "550e8400-e29b-41d4-a716-446655440000"

UUID v5 — Deterministic / Namespace-based

python snippet
import uuid
# SHA-1 hash of namespace + name — same inputs always produce the same UUID
# Useful for deduplication and content-addressable IDs
id = uuid.uuid5(uuid.NAMESPACE_DNS, "example.com")
print(str(id))  # → always "cfbff0d1-9375-5685-968c-48ce8b15ae17"

# Custom namespace
my_ns = uuid.uuid4()  # generate once, store it
record_id = uuid.uuid5(my_ns, "user:42")

UUID v1 — Timestamp + MAC (legacy)

python snippet
import uuid
# Encodes current timestamp + MAC address — sortable but leaks host info
# Only use for Cassandra timeuuid or legacy system compatibility
id = uuid.uuid1()
print(id.time)  # 100-nanosecond intervals since Oct 15, 1582

Real-World Use Cases

1. Django / SQLAlchemy model primary key

python snippet
import uuid
from django.db import models

class Order(models.Model):
    # Django natively supports UUIDField
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(auto_now_add=True)

# SQLAlchemy equivalent
from sqlalchemy import Column, String
from sqlalchemy.dialects.postgresql import UUID as PG_UUID

class Product(Base):
    __tablename__ = "products"
    id = Column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)

2. FastAPI request tracing

python snippet
import uuid
from fastapi import FastAPI, Request
import logging

app = FastAPI()
logger = logging.getLogger(__name__)

@app.middleware("http")
async def add_request_id(request: Request, call_next):
    request_id = str(uuid.uuid4())
    request.state.request_id = request_id
    response = await call_next(request)
    response.headers["X-Request-ID"] = request_id
    logger.info(f"[{request_id}] {request.method} {request.url.path}")
    return response

3. Deduplication with UUID v5

python snippet
import uuid

# Idempotent event ID — same event always gets the same UUID
EVENT_NAMESPACE = uuid.UUID("6ba7b810-9dad-11d1-80b4-00c04fd430c8")

def event_id(source: str, event_type: str, timestamp: str) -> str:
    key = f"{source}:{event_type}:{timestamp}"
    return str(uuid.uuid5(EVENT_NAMESPACE, key))

# Calling twice with same args returns the same UUID — safe to retry
id1 = event_id("payments", "charge.created", "2026-05-01T12:00:00Z")
id2 = event_id("payments", "charge.created", "2026-05-01T12:00:00Z")
assert id1 == id2  # True

Common Mistakes

Passing uuid.uuid4 instead of uuid.uuid4() as a default

In Django/SQLAlchemy, pass the function reference default=uuid.uuid4 (no parentheses). With parentheses, every row gets the same UUID generated at class definition time.

Storing as string when the DB supports a native UUID type

PostgreSQL has a native UUID column type that stores 16 bytes. Storing as VARCHAR(36) wastes 20 bytes per row and slows index lookups.

Using uuid.uuid1() in production web services

UUID v1 embeds your server's MAC address. This leaks network interface information and can be a privacy/security concern. Use v4 unless you specifically need Cassandra timeuuid.

How It Works

uuid.uuid4() calls os.urandom(16) internally to get 16 random bytes from the OS CSPRNG, then sets the version bits (bits 12–15 of octet 6 = 0100) and variant bits (bits 6–7 of octet 8 = 10).

The result is a uuid.UUID object. Call str() on it for the standard hyphenated format, .hex for 32-char no-hyphen, or .bytes for raw 16-byte binary.

The uuid.UUID object is immutable, hashable, and comparable — you can use it directly as a dict key or in a set.

Output Formats

str(id)

f47ac10b-58cc-4372-a567-0e02b2c3d479

id.hex

f47ac10b58cc4372a5670e02b2c3d479

id.bytes (16 bytes)

b'\xf4z\xc1\x0bX\xccCr\xa5g\x0e\x02\xb2\xc3\xd4y'

id.int

324716517733474852975027497220825710713

Best Practices

Use uuid.uuid4() as the default for all new code.

Pass the UUID object around — only convert to string at the boundary (DB write, API response).

Use uuid.uuid5() for deterministic IDs — great for idempotent event processing.

Performance

CPython generates roughly 1–3 million UUIDs/second on modern hardware. The bottleneck is os.urandom() — a syscall on every call.

For bulk generation, the uuid module is sufficient. If you need higher throughput, generate a large buffer with os.urandom(16 * n) and slice it manually.

Installation

# No installation needed — standard library

Available in Python 2.5+ and all Python 3.x versions. No pip install required.

Security

Entropy source: os.urandom() — maps to /dev/urandom on Linux/macOS and CryptGenRandom on Windows. Cryptographically secure.

Suitable for session tokens, CSRF tokens, and API keys. Do not use uuid.uuid1() for security-sensitive IDs.