Skip to main content

Timestamp-orderable UUIDs for Python, written in Rust.

Project description

UUIDT

Timestamp-orderable UUIDs for Python, written in Rust.

Installation

pip install uuidt

Usage

import uuidt

# Create a new UUIDT
u = uuidt.new('my-namespace')

# Print the UUIDT properties
print(u.namespace)
print(u.timestamp)
print(u.hostname)
print(u.random_chars)

# Convert to a string
print(str(u))

# Extract the timestamp from a UUIDT string
print(uuidt.extract_timestamp("cr3su3qh-4ium-00bk-00ip-vqlpgpomk3dv"))
# 1678562753992474990

Motivation

UUIDs are great for generating unique identifiers, but they are not necessarily time-orderable. This is a problem if you want to generate a UUID for a new record in a database, and then use that UUID to order the records by creation time.

Many databases avoid this problem using auto-incrementing integer IDs, but this isn't possible in distributed databases like CockroachDB, so a UUID is typically used as the primary key instead.

This library generates UUIDs that are time-orderable. The first 12 alphanumeric characters of the UUID are a nanosecond-precision timestamp which has been base-36 encoded, so they can be sorted lexicographically. The remaining 20 characters are a combination of a namespace, the hostname of the machine that generated the UUID, and a random string.

Technically, UUID1s are also time-orderable, but they are not guaranteed to be ordered by creation time, and it can be difficult to extract the timestamp from a UUID1.

Why Rust?

Mostly as a learning opportunity for me, though also for speed. The Rust implementation is significantly faster than the Python implementation, which used Numpy to convert to base-36.

What if I don't want the Rust implementation?

UUIDT should be installable as a wheel on most systems, but if you hate Ferris and want to use the Python implementation instead, here's some equivalent code:

import random
import socket
import time

import numpy as np

BASE = 36
DIVISOR = BASE - 1
CHARACTERS = list('0123456789abcdefghijklmnopqrstuvwxyz')[:BASE]


class UUIDT:
    def __init__(self, namespace: str, timestamp: int, hostname: str, random_chars: str):
        self.namespace = namespace
        self.timestamp = timestamp
        self.hostname = hostname
        self.random_chars = random_chars

    def __str__(self):
        hostname_enc = sum(self.hostname.encode('utf-8'))
        namespace_enc = sum(self.namespace.encode('utf-8'))

        timestamp_str = np.base_repr(self.timestamp, 36).lower()
        hostname_str = np.base_repr(hostname_enc, 36).lower()
        namespace_str = np.base_repr(namespace_enc, 36).lower()

        return (
            f'{timestamp_str[:8]}-{timestamp_str[8:]}-{hostname_str:0>4}-'
            f'{namespace_str:0>4}-{self.random_chars}'
        )


def new(namespace: str) -> UUIDT:
    timestamp = time.time_ns()
    hostname = socket.gethostname()
    random_chars = ''.join(random.choices(CHARACTERS, k=4))

    return UUIDT(namespace, timestamp, hostname, random_chars)

License

MIT

Using UUIDT in your project

While UUIDT is MIT licensed, I'm really curious to seeing the projects that use it! If you use UUIDT in your project, I'd love to hear about it! Please let me know by either opening an issue or sending me an email at the address in the pyproject.toml file.

Contributing

Contributions are welcome! Just open an issue or a pull request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

uuidt-0.1.0-cp37-abi3-win_amd64.whl (158.3 kB view details)

Uploaded CPython 3.7+ Windows x86-64

uuidt-0.1.0-cp37-abi3-win32.whl (150.5 kB view details)

Uploaded CPython 3.7+ Windows x86

uuidt-0.1.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ x86-64

uuidt-0.1.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (1.3 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ s390x

uuidt-0.1.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (1.2 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ ppc64le

uuidt-0.1.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.1 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ ARMv7l

uuidt-0.1.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ ARM64

uuidt-0.1.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl (1.1 MB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.5+ i686

uuidt-0.1.0-cp37-abi3-macosx_11_0_arm64.whl (275.2 kB view details)

Uploaded CPython 3.7+ macOS 11.0+ ARM64

uuidt-0.1.0-cp37-abi3-macosx_10_7_x86_64.whl (285.6 kB view details)

Uploaded CPython 3.7+ macOS 10.7+ x86-64

File details

Details for the file uuidt-0.1.0-cp37-abi3-win_amd64.whl.

File metadata

  • Download URL: uuidt-0.1.0-cp37-abi3-win_amd64.whl
  • Upload date:
  • Size: 158.3 kB
  • Tags: CPython 3.7+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.14.15

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 bcc04e1968a032f6c109f3902f89044dadaf437ba70e7a30f2338a907cb2dc77
MD5 80b329a3803205c6b9229d21102eb8cc
BLAKE2b-256 956935b8a2f87b889d217b333661bc394aafd040105be43489fb76b70f903497

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-win32.whl.

File metadata

  • Download URL: uuidt-0.1.0-cp37-abi3-win32.whl
  • Upload date:
  • Size: 150.5 kB
  • Tags: CPython 3.7+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.14.15

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-win32.whl
Algorithm Hash digest
SHA256 87c90824aec1889be0dc0349c5883fd1b49af0ad6b5a0201f5bd168e4c584d0e
MD5 d2f17cca2646d435c04800596f083835
BLAKE2b-256 85cb5dd51237942acca8fdd59b78614e2b119336766c6f86a6295a9d5dd40044

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bb2d24a999f6a995828e1962ca757cbbd9029a12643424d31d5d46eb3ad804bb
MD5 089c4edd6ca01bbb51e726f71818a5e1
BLAKE2b-256 b5c2e467ace69237c74b87960bfae4943caf05d755b324df44ef27974ef32258

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 a6e5192ccbfd6e2b116e83384cdd828232980baf2f193acb9259c00e23752406
MD5 51139253a3f0b59e5b04f706ef2a4ec5
BLAKE2b-256 9d29cc1e9468d629470d832b087d8ae874a0cf339fd8dd2a095bbb202ff1a306

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 dae742944904640ac83da53615255092cb29985cb59c37279f4c84901486e055
MD5 7e8a49e3336806eedd1540df2945115c
BLAKE2b-256 36bdb2d382daccba2f7025dcbd9be91a22406eef9103c8a4dad5950f58f8d890

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 6b9914617092136d14c3ad491a4c94c19f133d6107a1f53aa2fe1090c8447d9a
MD5 ac7e2575baf42ee1fe4db6c5ba309a3d
BLAKE2b-256 698177c039166a0cc80ed838585f9452037a027c9e2e4c71afdd8ce3a3432510

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2bad6aa4dece51c6c4274e57cbb8fbbf8bbfad0308b4248f5b940251938bd82f
MD5 6e4a6c4e3182255c3255f22a9af1b019
BLAKE2b-256 cbea87d0a74f3f025606284e900412c7ec1d438987e6bc23b3a2c6996349419d

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm Hash digest
SHA256 9f0a0dfe83ab3d0950e9c0b7aaee09e03ddfcc2b4fc0ed0333c7175a80e26a10
MD5 f7b2187c7064a99627acb160f58a1604
BLAKE2b-256 b20014161fc7ae075adfd32466700664492f74b04132f6e80749d743e870ac0b

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cb77f6474ebfe489afab772403023d008ea23a9f061b4fb341a42968ce09a25e
MD5 66bab36b3689e05e2e383c032d89f964
BLAKE2b-256 3ed7ec214a3ca30802293c66bf883c5da177badb5051fe4cf9a2127f1cf19e40

See more details on using hashes here.

File details

Details for the file uuidt-0.1.0-cp37-abi3-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for uuidt-0.1.0-cp37-abi3-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 25a82ee1733762258a7dd5b4eb83a71d132d2732eed3ef9ebfca1afa31a20dac
MD5 3185bc3a416d2237754eaea7b3407602
BLAKE2b-256 4aedb5d181cc2f2d05f327e8600c71803ce42e3d3c432e7d7e5e6873e2d4e978

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page