Skip to content

StreamUUID

Bases: UUID

Universally unique identifier for event streams.

Extends the standard UUID to support deterministic generation from stream names using a fixed namespace. Allows referencing streams by UUID or by name, ensuring consistent mapping between names and UUIDs.

Used as a base for stream identification.

Attributes:

Name Type Description
NAMESPACE UUID

Namespace used for deterministic name-based UUID generation.

uuid UUID | None

Create from explicit UUID for the stream.

name str | None

Create from name for deterministic UUID generation.

from_hex str | None

Create from hex string to construct the UUID.

Source code in event_sourcery/_event_store/stream_id.py
@dataclass(frozen=True, repr=False, eq=False)
class StreamUUID(UUID):
    """
    Universally unique identifier for event streams.

    Extends the standard UUID to support deterministic generation from stream names
    using a fixed namespace. Allows referencing streams by UUID or by name, ensuring
    consistent mapping between names and UUIDs.

    Used as a base for stream identification.

    Attributes:
        NAMESPACE (UUID): Namespace used for deterministic name-based UUID generation.
        uuid (UUID | None): Create from explicit UUID for the stream.
        name (str | None): Create from name for deterministic UUID generation.
        from_hex (str | None): Create from hex string to construct the UUID.
    """

    NAMESPACE = UUID("3a24a3ee-d33d-4266-93ab-7d8e256a6d44")

    uuid: InitVar[UUID | None] = None
    name: str | None = None
    from_hex: InitVar[str | None] = None

    def __post_init__(self, uuid: UUID | None, from_hex: str | None) -> None:
        if uuid is not None:
            super().__init__(bytes=uuid.bytes)
        elif self.name is not None:
            super().__init__(bytes=self._from_name(self.name).bytes)
        elif from_hex is not None:
            super().__init__(hex=from_hex)
        else:
            super().__init__(bytes=uuid4().bytes)

        if self.name and (expected := self._from_name(self.name)) != self:
            raise IncompatibleUuidAndName(self, expected, self.name)

    def _from_name(self, name: str) -> UUID:
        return uuid5(self.NAMESPACE, name)

    def __repr__(self) -> str:
        return f"{type(self).__name__}(hex={self!s}, name={self.name})"