Developer Lab · Python
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
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)
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
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)
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, 1582Real-World Use Cases
1. Django / SQLAlchemy model primary key
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
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 response3. Deduplication with UUID v5
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 # TrueCommon 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, Performance, and Security
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.
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.
Installation
UUID v4 (standard library)
# No installation needed - standard libraryAvailable in Python 2.5+ and all Python 3.x versions. No pip install required.
Frequently Asked Questions
How do I generate a UUID in Python?
Python ships a uuid module in its standard library, so there is nothing to install. uuid.uuid4() returns a random v4 UUID and str() gives the canonical form. Python 3 has no built-in v7, so use a package such as uuid6 or uuid-utils for time-ordered UUIDs.
Is uuid.uuid4() cryptographically secure?
Yes. uuid.uuid4() uses the platform CSPRNG (operating system secure random source), suitable for session tokens, API keys, and idempotency keys. Do not use non-cryptographic random sources for security-sensitive identifiers.
What is the difference between UUID v4 and v7 in Python?
UUID v4 (uuid.uuid4() or equivalent) is fully random and not sortable. UUID v7 embeds a millisecond timestamp for chronological sorting (RFC 9562). Use v4 for general-purpose IDs; use v7 for database primary keys at scale.
Do I need to install a package for UUID generation in Python?
No additional package is required for basic v4 generation in Python. Check the Installation section for version-specific notes.
How do I validate a UUID string in Python?
Use the platform's UUID parse/validation function, or test against the RFC 4122 regex: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Always validate external input at API boundaries.
Should I use UUIDs as database primary keys in Python applications?
UUIDs work well as primary keys for distributed systems. Prefer native UUID/BINARY(16) column types over VARCHAR(36). For very large tables, consider UUID v7 for better B-tree insert locality.
Can I generate UUIDs in Python without a network connection?
Yes. UUID generation uses local OS entropy sources and does not require network access. Each call is independent and thread-safe on modern platforms.
What output formats are available in Python?
The standard hyphenated lowercase string (36 chars) is the default. Most APIs also support 32-char hex (no hyphens) and 16-byte binary formats. Use string format for APIs and binary for database storage.
What RFC standards apply to Python UUID generation?
Version 4 UUIDs follow RFC 4122. UUID v7 follows RFC 9562 (May 2024). Ensure your chosen method produces compliant version and variant bits.
When should I avoid UUID v1?
Avoid UUID v1 in security-sensitive contexts - it embeds MAC address and timestamp information. Prefer v4 (uuid.uuid4() or equivalent) unless you need legacy Cassandra timeuuid compatibility.
Key definitions
- UUID
- 128-bit universally unique identifier, usually shown as 36 hex characters with hyphens.
- CSPRNG
- Cryptographically secure pseudo-random number generator - the entropy source behind secure UUID generation.
- RFC 4122
- IETF standard defining UUID versions 1 through 5. Version 4 is random.
- RFC 9562
- IETF standard adding UUID versions 6, 7, and 8. Version 7 is time-ordered.