diff --git a/homeassistant/core.py b/homeassistant/core.py index a55ca358e39..949c94038aa 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -72,7 +72,7 @@ from .exceptions import ( ServiceNotFound, Unauthorized, ) -from .util import dt as dt_util, location, uuid as uuid_util +from .util import dt as dt_util, location, ulid as ulid_util from .util.async_ import ( fire_coroutine_threadsafe, run_callback_threadsafe, @@ -696,7 +696,7 @@ class Context: user_id: str | None = attr.ib(default=None) parent_id: str | None = attr.ib(default=None) - id: str = attr.ib(factory=uuid_util.random_uuid_hex) + id: str = attr.ib(factory=ulid_util.ulid_hex) def as_dict(self) -> dict[str, str | None]: """Return a dictionary representation of the context.""" diff --git a/homeassistant/util/ulid.py b/homeassistant/util/ulid.py new file mode 100644 index 00000000000..888b5b2074b --- /dev/null +++ b/homeassistant/util/ulid.py @@ -0,0 +1,25 @@ +"""Helpers to generate ulids.""" + +from random import getrandbits +import time + + +# In the future once we require python 3.10 and above, we can +# create a new function that uses base64.b32encodehex to shorten +# these to 26 characters. +def ulid_hex() -> str: + """Generate a ULID in hex that will work for a UUID. + + This ulid should not be used for cryptographically secure + operations. + + 01AN4Z07BY 79KA1307SR9X4MV3 + |----------| |----------------| + Timestamp Randomness + 48bits 80bits + + This string can be converted with https://github.com/ahawker/ulid + + ulid.from_uuid(uuid.UUID(value)) + """ + return f"{int(time.time()*1000):012x}{getrandbits(80):020x}" diff --git a/tests/util/test_ulid.py b/tests/util/test_ulid.py new file mode 100644 index 00000000000..fc5d2af8c87 --- /dev/null +++ b/tests/util/test_ulid.py @@ -0,0 +1,11 @@ +"""Test Home Assistant ulid util methods.""" + +import uuid + +import homeassistant.util.ulid as ulid_util + + +async def test_ulid_util_uuid_hex(): + """Verify we can generate a ulid.""" + assert len(ulid_util.ulid_hex()) == 32 + assert uuid.UUID(ulid_util.ulid_hex())