Skip to content

Quick Start

Install pUUID from the PyPI repositories via pip:

pip install pUUID

For SQLAlchemy support, include the extra:

pip install 'pUUID[sqlalchemy]'

Basic Usage

Define a custom PUUID class by inheriting from a versioned base and specifying a prefix.

from typing import Literal
from uuid import UUID
from puuid import PUUIDv4

class UserUUID(PUUIDv4[Literal["user"]]): ...

# Generate a new random PUUID
user_id = UserUUID.factory()
print(user_id)
# user_b100f10f-6876-4b61-984f-2c74be42fcd4

# Initialize from an existing UUID
uuid_obj = UUID('b100f10f-6876-4b61-984f-2c74be42fcd4')
user_id = UserUUID(uuid=uuid_obj)

# Serialization
serial: str = user_id.to_string()

# Deserialization
user_id: UserUUID = UserUUID.from_string(serial)

Supported Variants

pUUID supports UUID versions 1, 3, 4, 5, 6, 7, and 8.

from uuid import NAMESPACE_DNS
from puuid import PUUIDv5, PUUIDv7, PUUIDv8


# Time-based (ordered) UUIDs
class EventUUID(PUUIDv7[Literal["evt"]]): ...

print(EventUUID.factory())
# evt_019b956e-ed25-70db-9d0a-0f30fb9047c2


# Name-based UUIDs
class DomainUUID(PUUIDv5[Literal["dom"]]): ...

dom_id = DomainUUID.factory(namespace=NAMESPACE_DNS, name="digon.io")
print(dom_id)
# dom_cfbff0d1-9375-5685-968c-48ce8b15ae17


# Custom UUIDs
class ChecksumUUID(PUUIDv8[Literal["chk"]]): ...

chk_id = ChecksumUUID.factory(a=0x123, b=0x456, c=0x789)
print(chk_id)
# chk_00000000-0123-8456-8000-000000000789

Pydantic Integration

PUUIDs work as field types in Pydantic models with built-in validation.

from pydantic import BaseModel

class User(BaseModel):
    user_id: UserUUID

user = User(user_id=UserUUID.factory())
# Validation works with strings too
user = User(user_id="user_b100f10f-6876-4b61-984f-2c74be42fcd4")

SQLAlchemy Integration

Use SqlPUUID to map PUUID classes to database columns.

from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from puuid.sqlalchemy import SqlPUUID

class BaseORM(DeclarativeBase): ...

class UserORM(BaseORM):
    __tablename__ = "users"

    id: Mapped[UserUUID] = mapped_column(
        SqlPUUID(UserUUID),
        primary_key=True,
        default=UserUUID.factory,
    )

Prefix Length Matching

If you later change the PUUID prefix without updating the database column width via a migration, the database might raise an error or truncate the PUUID.

Calculation logic: prefix_length + 1 (separator) + 36 (UUID) = Total Column Width.