A Python library that implements UUIDv7 generation and parsing.
It supports conversion to and from datetime
values, ensuring full sorting compatibility with UUIDs produced by PostgreSQL’s pg_uuidv7
extension, PostgreSQL 18’s built-in uuid7
, and Python 3.14’s uuid.uuid7
.
Unlike the standard uuid.uuid7
, this library also allows generating UUIDs for specific timestamps.
UUIDv7 is a time-sortable UUID format composed of a timestamp and random bits. Our implementation follows the UUIDv7 specification, which provides flexibility in ensuring monotonicity. We utilize microseconds for sub-millisecond precision within the timestamp; this acts as a stateless monotonic counter for UUIDs generated within the same millisecond and leaves more room for entropy compared to using nanoseconds.
Bits | Size (bits) | Field | Description |
---|---|---|---|
0–47 | 48 | timestamp (ms) | Unix timestamp in milliseconds (sortable) |
48–51 | 4 | version | UUID version (0b0111 for v7) |
52–71 | 20 | sub-ms (μs) | Sub-millisecond fraction (0–999,999) |
72–127 | 56 | random | Random bits (includes UUID variant information) |
This design makes UUIDv7 globally sortable by creation time (1 μs resolution) while retaining enough entropy for distributed uniqueness.
- Compatible with
pg_uuidv7
’suuid_generate_v7()
,uuid_v7_to_timestamptz()
,uuid_timestamptz_to_v7()
functions. - Sorting compatible with Python 3.14's
uuid.uuid7()
- Provides conversion between
UUIDv7
anddatetime
. - Supports timezone-aware and naive datetime conversions.
The widely-used uuid7
Python package uses
a different timestamp scheme, which is not compatible with sorting behavior as implemented in the PostgreSQL
pg_uuidv7
extension. This package ensures compatibility, ensuring that UUIDv7s generated will sort correctly alongside
those produced by pg_uuidv7
.
Key differences between this library and Python 3.14's built-in uuid7:
- Timestamp Implementation: This library works with μs (microseconds), while Python 3.14+ uses a counter mechanism
- Conversion Utilities: This library provides uuid7 ↔ datetime conversion, which isn't available in the standard library implementation (at the time of writing)
- PostgreSQL Compatibility: Both implementations are sorting compatible with the
pg_uuidv7
PostgreSQL extension
pip install edwh-uuid7
Here are examples of how to use edwh-uuid7
:
from edwh_uuid7 import uuid7 # or `uuid_generate_v7`
uuid = uuid7()
print(f"Generated UUIDv7: {uuid}")
from edwh_uuid7 import uuid7, uuid7_to_datetime # or uuid_generate_v7, uuid_v7_to_timestamptz
uuid = uuid7() # UUID('0196905b-4434-74ef-aa27-442be7069beb')
datetime_value = uuid7_to_datetime(uuid) # datetime.datetime(2025, 5, 2, 9, 37, 2, 516000, tzinfo=datetime.timezone.utc)
print(f"Corresponding datetime: {datetime_value}") # 2025-05-02 09:37:02.516000+00:00
This library provides enhanced timestamp precision capabilities:
- Default Precision: By default, uuid7 supports millisecond precision
- Enhanced Recovery: When working with UUIDs created by this library (
uuid7()
oruuid7(timestamp_ns=...)
), you can enablehigh_precision=True
to recover datetime values with microsecond accuracy
Example:
now = datetime.fromtimestamp(time.time()) # datetime.datetime(2025, 5, 9, 17, 53, 50, 514106)
uuid = datetime_to_uuid7(now) # UUID('0196b5c0-c0b2-719e-802c-9964c4992a66')
uuid7_to_datetime(uuid) # datetime(2025, 5, 9, 15, 53, 50, 514000, tzinfo=datetime.timezone.utc)
uuid7_to_datetime(uuid, high_precision=True) # datetime(2025, 5, 9, 15, 53, 50, 514106, tzinfo=datetime.timezone.utc)
from edwh_uuid7.core import datetime_to_uuid7 # or uuid_timestamptz_to_v7
from datetime import datetime, timezone
dt = datetime(2025, 5, 2, 9, 37, 2, 516000, tzinfo=timezone.utc)
uuid_from_dt = datetime_to_uuid7(dt) # UUID('0196905b-4434-7000-8012-620314c8b88b')
print(f"UUIDv7 from datetime: {uuid_from_dt}") # 0196905b-4434-7000-8012-620314c8b88b
from edwh_uuid7 import uuid7, uuid7_to_datetime # or uuid_generate_v7, uuid_v7_to_timestamptz
from zoneinfo import ZoneInfo
uuid = uuid7() # UUID('0196905f-0339-769a-9f0b-8fedc645a688')
datetime_value = uuid7_to_datetime(uuid, tz=ZoneInfo("Europe/Amsterdam")) # datetime.datetime(2025, 5, 2, 11, 41, 8, 25000, tzinfo=zoneinfo.ZoneInfo(key='Europe/Amsterdam'))
print(f"Generated UUID: {uuid}") # 0196905f-0339-769a-9f0b-8fedc645a688
print(f"Timezone-aware datetime: {datetime_value}") # 2025-05-02 11:41:08.025000+02:00
While microseconds are used to ensure correct sorting, accuracy is limited (truncated) when converting back to
datetime
, consistent with the behavior of the pg_uuidv7
function uuid_timestamptz_to_v7
.
For example:
Input: 2025-05-02 08:46:48.307329+00:00
UUID conversion: 0196902d-45f3-7505-8038-7795a5ec9a1b (example)
Converted Back: 2025-05-02 08:46:48.307000+00:00
This truncation is by design (in favor of entropy) and aligns with the PostgreSQL pg_uuidv7
implementation.