New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

typeid-python

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typeid-python - pypi Package Compare versions

Comparing version
0.3.6
to
0.3.7
+21
LICENSE
MIT License
Copyright (c) 2025 Murad Akhundov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Metadata-Version: 2.4
Name: typeid-python
Version: 0.3.7
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Requires-Dist: uuid-utils>=0.12.0
Requires-Dist: click ; extra == 'cli'
Requires-Dist: pyyaml ; extra == 'yaml'
Provides-Extra: cli
Provides-Extra: yaml
License-File: LICENSE
Summary: Python implementation of TypeIDs: type-safe, K-sortable, and globally unique identifiers inspired by Stripe IDs
Keywords: typeid,uuid,rust,guid,uuid7
Author-email: Murad Akhundov <akhundov1murad@gmail.com>
Requires-Python: >=3.10, <4
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/akhundMurad/typeid-python
Project-URL: Repository, https://github.com/akhundMurad/typeid-python
Project-URL: Bug Tracker, https://github.com/akhundMurad/typeid-python/issues
# TypeID Python
[![Run Tests](https://github.com/akhundMurad/typeid-python/actions/workflows/test.yml/badge.svg)](https://github.com/akhundMurad/typeid-python/actions/workflows/test.yml)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/typeid-python?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/typeid-python)
[![PyPI - Version](https://img.shields.io/pypi/v/typeid-python?color=green)](https://pypi.org/project/typeid-python/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/typeid-python?color=green)](https://pypi.org/project/typeid-python/)
A **high-performance Python implementation of [TypeIDs](https://github.com/jetpack-io/typeid)** — type-safe,
sortable identifiers based on **UUIDv7**.
TypeIDs are designed for modern systems where identifiers should be:
- globally unique
- sortable by creation time
- safe to expose externally
- easy to reason about in logs, APIs, and databases
This library provides a Python package with optional Rust acceleration.
## Key features
- ✅ UUIDv7-based, time-sortable identifiers
- ✅ Type-safe prefixes (`user_`, `order_`, …)
- ✅ Human-readable and URL-safe
- ✅ Fast generation & parsing (Rust-accelerated)
- ✅ CLI tools (`new`, `encode`, `decode`, `explain`)
- ✅ Schema-based ID explanations (JSON / YAML)
- ✅ Fully offline, no external services
## Performance
TypeID is optimized for **real-world performance**, not just correctness.
### Benchmark summary (mean time)
| Operation | Before Rust | Rust + optimizations |
| --------- | ----------- | -------------------- |
| Generate | 3.47 µs | **0.70 µs** |
| Parse | 2.08 µs | **1.30 µs** |
| Workflow | 5.52 µs | **2.25 µs** |
### Highlights
* 🚀 **~5× faster generation**
* ⚡ **~1.6× faster parsing**
* 🔁 **~2.5× faster end-to-end workflows**
Benchmarks are:
* reproducible
* committed as raw JSON
* runnable locally via `bench/`
See [`Docs: Performance`](https://akhundmurad.github.io/typeid-python/performance/) for details.
## Installation
### Core
```console
$ pip install typeid-python
```
Included:
* Rust base32 encode/decode
* `uuid-utils` for fast UUIDv7 generation
### Other optional extras
```console
$ pip install typeid-python[yaml] # YAML schema support
$ pip install typeid-python[cli] # CLI tools
```
Extras are **strictly optional**.
## Usage
### Basic
```python
from typeid import TypeID
tid = TypeID(prefix="user")
assert tid.prefix == "user"
assert isinstance(tid.suffix, str)
assert str(tid).startswith("user_")
```
### From string
```python
from typeid import TypeID
tid = TypeID.from_string("user_01h45ytscbebyvny4gc8cr8ma2")
assert tid.prefix == "user"
```
### From UUIDv7
```python
from typeid import TypeID
from uuid_utils import uuid7
u = uuid7()
tid = TypeID.from_uuid(prefix="user", suffix=u)
assert tid.uuid.version == 7
```
### Typed prefixes
```python
from typing import Literal
from typeid import TypeID, typeid_factory
UserID = TypeID[Literal["user"]]
gen_user_id = typeid_factory("user")
user_id = gen_user_id()
```
## CLI
```console
$ pip install typeid-python[cli]
```
Generate:
```console
$ typeid new -p user
user_01h2xcejqtf2nbrexx3vqjhp41
```
Decode:
```console
$ typeid decode user_01h2xcejqtf2nbrexx3vqjhp41
uuid: 0188bac7-4afa-78aa-bc3b-bd1eef28d881
```
Encode:
```console
$ typeid encode 0188bac7-4afa-78aa-bc3b-bd1eef28d881 --prefix user
```
## ✨ `typeid explain` — understand any ID
```console
$ typeid explain user_01h45ytscbebyvny4gc8cr8ma2
```
Outputs:
```yaml
parsed:
prefix: user
uuid: 01890bf0-846f-7762-8605-5a3abb40e0e5
created_at: 2025-03-12T10:41:23Z
sortable: true
```
Works **without schema**, fully offline.
## Schema-based explanations
Define meaning for prefixes using JSON or YAML.
Example (`typeid.schema.json`):
```json
{
"schema_version": 1,
"types": {
"user": {
"name": "User",
"owner_team": "identity-platform",
"pii": true
}
}
}
```
Then:
```console
$ typeid explain user_01h45ytscbebyvny4gc8cr8ma2
```
Read more here: ["Docs: Explain"](https://akhundmurad.github.io/typeid-python/performance/).
## Design principles
* **Non-breaking**: stable APIs
* **Optional acceleration**: Rust is opt-in
* **Lazy evaluation**: work is done only when needed
* **Explainability**: identifiers carry meaning
* **Transparency**: performance claims are backed by data
> Think of TypeID as
> **UUIDs + semantics + observability — without sacrificing speed**
## License
MIT
[project]
name = "typeid-python"
version = "0.3.7"
description = "Python implementation of TypeIDs: type-safe, K-sortable, and globally unique identifiers inspired by Stripe IDs"
authors = [{ name = "Murad Akhundov", email = "akhundov1murad@gmail.com" }]
requires-python = ">=3.10,<4"
readme = "README.md"
license = { file = "LICENSE" }
keywords = ["typeid", "uuid", "rust", "guid", "uuid7"]
classifiers = [
"Development Status :: 3 - Alpha",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Operating System :: OS Independent",
]
dependencies = ["uuid-utils>=0.12.0"]
[project.optional-dependencies]
cli = ["click"]
yaml = ["PyYAML"]
[project.urls]
Homepage = "https://github.com/akhundMurad/typeid-python"
Repository = "https://github.com/akhundMurad/typeid-python"
"Bug Tracker" = "https://github.com/akhundMurad/typeid-python/issues"
[project.scripts]
typeid = "typeid.cli:cli"
[dependency-groups]
dev = [
"pytest>=7.3.2,<8",
"black>=23.3.0,<24",
"mypy>=1.3.0,<2",
"requests>=2.31.0,<3",
"ruff>=0.14.5,<0.15",
"twine>=6.2.0,<7",
"pyyaml>=6.0",
"mkdocs-material>=9.7.1",
"mkdocstrings[python]>=1.0.0",
"mkdocs-git-revision-date-localized-plugin>=1.5.0",
"mkdocs-gen-files>=0.6.0",
"mkdocs-literate-nav>=0.6.2",
"mkdocs-section-index>=0.3.10",
"pytest-markdown-docs>=0.9.0",
"pytest-benchmark>=5.0.1",
"maturin>=1.5; platform_system != 'Windows'",
]
[build-system]
requires = ["maturin>=1.5"]
build-backend = "maturin"
[tool.maturin]
python-source = "."
manifest-path = "rust-base32/Cargo.toml"
module-name = "typeid._base32"
features = ["pyo3/extension-module"]
include = ["LICENSE", "README.md", "typeid/**", "rust-base32/**"]
# TypeID Python
[![Run Tests](https://github.com/akhundMurad/typeid-python/actions/workflows/test.yml/badge.svg)](https://github.com/akhundMurad/typeid-python/actions/workflows/test.yml)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/typeid-python?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/typeid-python)
[![PyPI - Version](https://img.shields.io/pypi/v/typeid-python?color=green)](https://pypi.org/project/typeid-python/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/typeid-python?color=green)](https://pypi.org/project/typeid-python/)
A **high-performance Python implementation of [TypeIDs](https://github.com/jetpack-io/typeid)** — type-safe,
sortable identifiers based on **UUIDv7**.
TypeIDs are designed for modern systems where identifiers should be:
- globally unique
- sortable by creation time
- safe to expose externally
- easy to reason about in logs, APIs, and databases
This library provides a Python package with optional Rust acceleration.
## Key features
- ✅ UUIDv7-based, time-sortable identifiers
- ✅ Type-safe prefixes (`user_`, `order_`, …)
- ✅ Human-readable and URL-safe
- ✅ Fast generation & parsing (Rust-accelerated)
- ✅ CLI tools (`new`, `encode`, `decode`, `explain`)
- ✅ Schema-based ID explanations (JSON / YAML)
- ✅ Fully offline, no external services
## Performance
TypeID is optimized for **real-world performance**, not just correctness.
### Benchmark summary (mean time)
| Operation | Before Rust | Rust + optimizations |
| --------- | ----------- | -------------------- |
| Generate | 3.47 µs | **0.70 µs** |
| Parse | 2.08 µs | **1.30 µs** |
| Workflow | 5.52 µs | **2.25 µs** |
### Highlights
* 🚀 **~5× faster generation**
* ⚡ **~1.6× faster parsing**
* 🔁 **~2.5× faster end-to-end workflows**
Benchmarks are:
* reproducible
* committed as raw JSON
* runnable locally via `bench/`
See [`Docs: Performance`](https://akhundmurad.github.io/typeid-python/performance/) for details.
## Installation
### Core
```console
$ pip install typeid-python
```
Included:
* Rust base32 encode/decode
* `uuid-utils` for fast UUIDv7 generation
### Other optional extras
```console
$ pip install typeid-python[yaml] # YAML schema support
$ pip install typeid-python[cli] # CLI tools
```
Extras are **strictly optional**.
## Usage
### Basic
```python
from typeid import TypeID
tid = TypeID(prefix="user")
assert tid.prefix == "user"
assert isinstance(tid.suffix, str)
assert str(tid).startswith("user_")
```
### From string
```python
from typeid import TypeID
tid = TypeID.from_string("user_01h45ytscbebyvny4gc8cr8ma2")
assert tid.prefix == "user"
```
### From UUIDv7
```python
from typeid import TypeID
from uuid_utils import uuid7
u = uuid7()
tid = TypeID.from_uuid(prefix="user", suffix=u)
assert tid.uuid.version == 7
```
### Typed prefixes
```python
from typing import Literal
from typeid import TypeID, typeid_factory
UserID = TypeID[Literal["user"]]
gen_user_id = typeid_factory("user")
user_id = gen_user_id()
```
## CLI
```console
$ pip install typeid-python[cli]
```
Generate:
```console
$ typeid new -p user
user_01h2xcejqtf2nbrexx3vqjhp41
```
Decode:
```console
$ typeid decode user_01h2xcejqtf2nbrexx3vqjhp41
uuid: 0188bac7-4afa-78aa-bc3b-bd1eef28d881
```
Encode:
```console
$ typeid encode 0188bac7-4afa-78aa-bc3b-bd1eef28d881 --prefix user
```
## ✨ `typeid explain` — understand any ID
```console
$ typeid explain user_01h45ytscbebyvny4gc8cr8ma2
```
Outputs:
```yaml
parsed:
prefix: user
uuid: 01890bf0-846f-7762-8605-5a3abb40e0e5
created_at: 2025-03-12T10:41:23Z
sortable: true
```
Works **without schema**, fully offline.
## Schema-based explanations
Define meaning for prefixes using JSON or YAML.
Example (`typeid.schema.json`):
```json
{
"schema_version": 1,
"types": {
"user": {
"name": "User",
"owner_team": "identity-platform",
"pii": true
}
}
}
```
Then:
```console
$ typeid explain user_01h45ytscbebyvny4gc8cr8ma2
```
Read more here: ["Docs: Explain"](https://akhundmurad.github.io/typeid-python/performance/).
## Design principles
* **Non-breaking**: stable APIs
* **Optional acceleration**: Rust is opt-in
* **Lazy evaluation**: work is done only when needed
* **Explainability**: identifiers carry meaning
* **Transparency**: performance claims are backed by data
> Think of TypeID as
> **UUIDs + semantics + observability — without sacrificing speed**
## License
MIT
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indoc"
version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
dependencies = [
"rustversion",
]
[[package]]
name = "libc"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "portable-atomic"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
[[package]]
name = "proc-macro2"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pyo3"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d"
dependencies = [
"indoc",
"libc",
"memoffset",
"once_cell",
"portable-atomic",
"pyo3-build-config",
"pyo3-ffi",
"pyo3-macros",
"unindent",
]
[[package]]
name = "pyo3-build-config"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6"
dependencies = [
"target-lexicon",
]
[[package]]
name = "pyo3-ffi"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089"
dependencies = [
"libc",
"pyo3-build-config",
]
[[package]]
name = "pyo3-macros"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn",
]
[[package]]
name = "pyo3-macros-backend"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9"
dependencies = [
"heck",
"proc-macro2",
"pyo3-build-config",
"quote",
"syn",
]
[[package]]
name = "quote"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "syn"
version = "2.0.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "target-lexicon"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba"
[[package]]
name = "typeid-base32"
version = "0.3.7"
dependencies = [
"pyo3",
]
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "unindent"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
[package]
name = "typeid-base32"
version = "0.3.7"
edition = "2021"
description = "Rust-accelerated base32 codec for typeid-python"
license = "MIT"
repository = "https://github.com/akhundMurad/typeid-python"
[lib]
name = "_base32"
crate-type = ["cdylib"]
[dependencies]
pyo3 = { version = "0.27.2", features = ["extension-module"] }
use pyo3::exceptions::PyRuntimeError;
use pyo3::prelude::*;
use pyo3::types::PyModule;
const SUFFIX_LEN: usize = 26;
const UUID_LEN: usize = 16;
const ALPHABET: &[u8; 32] = b"0123456789abcdefghjkmnpqrstvwxyz";
#[inline]
fn build_table() -> [u8; 256] {
let mut t = [0xFFu8; 256];
for (i, &ch) in ALPHABET.iter().enumerate() {
t[ch as usize] = i as u8;
}
t
}
#[pyfunction]
fn encode(src: &[u8]) -> PyResult<String> {
if src.len() != UUID_LEN {
return Err(PyRuntimeError::new_err("Invalid length (expected 16 bytes)."));
}
let b = src;
let mut out = [0u8; SUFFIX_LEN];
// Timestamp (6 bytes => 10 chars)
out[0] = ALPHABET[((b[0] & 0b1110_0000) >> 5) as usize];
out[1] = ALPHABET[(b[0] & 0b0001_1111) as usize];
out[2] = ALPHABET[((b[1] & 0b1111_1000) >> 3) as usize];
out[3] = ALPHABET[(((b[1] & 0b0000_0111) << 2) | ((b[2] & 0b1100_0000) >> 6)) as usize];
out[4] = ALPHABET[((b[2] & 0b0011_1110) >> 1) as usize];
out[5] = ALPHABET[(((b[2] & 0b0000_0001) << 4) | ((b[3] & 0b1111_0000) >> 4)) as usize];
out[6] = ALPHABET[(((b[3] & 0b0000_1111) << 1) | ((b[4] & 0b1000_0000) >> 7)) as usize];
out[7] = ALPHABET[((b[4] & 0b0111_1100) >> 2) as usize];
out[8] = ALPHABET[(((b[4] & 0b0000_0011) << 3) | ((b[5] & 0b1110_0000) >> 5)) as usize];
out[9] = ALPHABET[(b[5] & 0b0001_1111) as usize];
// Entropy (10 bytes => 16 chars)
out[10] = ALPHABET[((b[6] & 0b1111_1000) >> 3) as usize];
out[11] = ALPHABET[(((b[6] & 0b0000_0111) << 2) | ((b[7] & 0b1100_0000) >> 6)) as usize];
out[12] = ALPHABET[((b[7] & 0b0011_1110) >> 1) as usize];
out[13] = ALPHABET[(((b[7] & 0b0000_0001) << 4) | ((b[8] & 0b1111_0000) >> 4)) as usize];
out[14] = ALPHABET[(((b[8] & 0b0000_1111) << 1) | ((b[9] & 0b1000_0000) >> 7)) as usize];
out[15] = ALPHABET[((b[9] & 0b0111_1100) >> 2) as usize];
out[16] = ALPHABET[(((b[9] & 0b0000_0011) << 3) | ((b[10] & 0b1110_0000) >> 5)) as usize];
out[17] = ALPHABET[(b[10] & 0b0001_1111) as usize];
out[18] = ALPHABET[((b[11] & 0b1111_1000) >> 3) as usize];
out[19] = ALPHABET[(((b[11] & 0b0000_0111) << 2) | ((b[12] & 0b1100_0000) >> 6)) as usize];
out[20] = ALPHABET[((b[12] & 0b0011_1110) >> 1) as usize];
out[21] = ALPHABET[(((b[12] & 0b0000_0001) << 4) | ((b[13] & 0b1111_0000) >> 4)) as usize];
out[22] = ALPHABET[(((b[13] & 0b0000_1111) << 1) | ((b[14] & 0b1000_0000) >> 7)) as usize];
out[23] = ALPHABET[((b[14] & 0b0111_1100) >> 2) as usize];
out[24] = ALPHABET[(((b[14] & 0b0000_0011) << 3) | ((b[15] & 0b1110_0000) >> 5)) as usize];
out[25] = ALPHABET[(b[15] & 0b0001_1111) as usize];
// Safe because alphabet is ASCII
Ok(String::from_utf8(out.to_vec()).unwrap())
}
#[pyfunction]
fn decode(s: &str) -> PyResult<Vec<u8>> {
if s.len() != SUFFIX_LEN {
return Err(PyRuntimeError::new_err("Invalid length (expected 26 chars)."));
}
let t = build_table();
let bytes = s.as_bytes();
// Validate
for &ch in bytes {
if t[ch as usize] == 0xFF {
return Err(PyRuntimeError::new_err("Invalid base32 character."));
}
}
#[inline]
fn v(t: &[u8; 256], bytes: &[u8], i: usize) -> u8 {
t[bytes[i] as usize]
}
let mut out = [0u8; UUID_LEN];
// Timestamp (48 bits)
out[0] = (v(&t, bytes, 0) << 5) | v(&t, bytes, 1);
out[1] = (v(&t, bytes, 2) << 3) | (v(&t, bytes, 3) >> 2);
out[2] = ((v(&t, bytes, 3) & 3) << 6) | (v(&t, bytes, 4) << 1) | (v(&t, bytes, 5) >> 4);
out[3] = ((v(&t, bytes, 5) & 15) << 4) | (v(&t, bytes, 6) >> 1);
out[4] = ((v(&t, bytes, 6) & 1) << 7) | (v(&t, bytes, 7) << 2) | (v(&t, bytes, 8) >> 3);
out[5] = ((v(&t, bytes, 8) & 7) << 5) | v(&t, bytes, 9);
// Entropy (80 bits)
out[6] = (v(&t, bytes, 10) << 3) | (v(&t, bytes, 11) >> 2);
out[7] = ((v(&t, bytes, 11) & 3) << 6) | (v(&t, bytes, 12) << 1) | (v(&t, bytes, 13) >> 4);
out[8] = ((v(&t, bytes, 13) & 15) << 4) | (v(&t, bytes, 14) >> 1);
out[9] = ((v(&t, bytes, 14) & 1) << 7) | (v(&t, bytes, 15) << 2) | (v(&t, bytes, 16) >> 3);
out[10] = ((v(&t, bytes, 16) & 7) << 5) | v(&t, bytes, 17);
out[11] = (v(&t, bytes, 18) << 3) | (v(&t, bytes, 19) >> 2);
out[12] = ((v(&t, bytes, 19) & 3) << 6) | (v(&t, bytes, 20) << 1) | (v(&t, bytes, 21) >> 4);
out[13] = ((v(&t, bytes, 21) & 15) << 4) | (v(&t, bytes, 22) >> 1);
out[14] = ((v(&t, bytes, 22) & 1) << 7) | (v(&t, bytes, 23) << 2) | (v(&t, bytes, 24) >> 3);
out[15] = ((v(&t, bytes, 24) & 7) << 5) | v(&t, bytes, 25);
Ok(out.to_vec())
}
#[pymodule]
fn _base32(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(encode, m)?)?;
m.add_function(wrap_pyfunction!(decode, m)?)?;
Ok(())
}
-2
[console_scripts]
typeid=typeid.cli:cli
MIT License
Copyright (c) 2023 Murad Akhundov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Metadata-Version: 2.4
Name: typeid-python
Version: 0.3.6
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Requires-Dist: uuid-utils>=0.12.0
Requires-Dist: click ; extra == 'cli'
Requires-Dist: pyyaml ; extra == 'yaml'
Provides-Extra: cli
Provides-Extra: yaml
License-File: LICENSE
Summary: Python implementation of TypeIDs: type-safe, K-sortable, and globally unique identifiers inspired by Stripe IDs
Keywords: typeid,uuid,rust,guid,uuid7
Author-email: Murad Akhundov <akhundov1murad@gmail.com>
License-Expression: MIT
Requires-Python: >=3.10, <4
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/akhundMurad/typeid-python
Project-URL: Repository, https://github.com/akhundMurad/typeid-python
Project-URL: Bug Tracker, https://github.com/akhundMurad/typeid-python/issues
# TypeID Python
[![Run Tests](https://github.com/akhundMurad/typeid-python/actions/workflows/test.yml/badge.svg)](https://github.com/akhundMurad/typeid-python/actions/workflows/test.yml)
[![PyPI Downloads](https://static.pepy.tech/personalized-badge/typeid-python?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/typeid-python)
[![PyPI - Version](https://img.shields.io/pypi/v/typeid-python?color=green)](https://pypi.org/project/typeid-python/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/typeid-python?color=green)](https://pypi.org/project/typeid-python/)
A **high-performance Python implementation of [TypeIDs](https://github.com/jetpack-io/typeid)** — type-safe,
sortable identifiers based on **UUIDv7**.
TypeIDs are designed for modern systems where identifiers should be:
- globally unique
- sortable by creation time
- safe to expose externally
- easy to reason about in logs, APIs, and databases
This library provides a Python package with optional Rust acceleration.
## Key features
- ✅ UUIDv7-based, time-sortable identifiers
- ✅ Type-safe prefixes (`user_`, `order_`, …)
- ✅ Human-readable and URL-safe
- ✅ Fast generation & parsing (Rust-accelerated)
- ✅ CLI tools (`new`, `encode`, `decode`, `explain`)
- ✅ Schema-based ID explanations (JSON / YAML)
- ✅ Fully offline, no external services
## Performance
TypeID is optimized for **real-world performance**, not just correctness.
### Benchmark summary (mean time)
| Operation | Before Rust | Rust + optimizations |
| --------- | ----------- | -------------------- |
| Generate | 3.47 µs | **0.70 µs** |
| Parse | 2.08 µs | **1.30 µs** |
| Workflow | 5.52 µs | **2.25 µs** |
### Highlights
* 🚀 **~5× faster generation**
* ⚡ **~1.6× faster parsing**
* 🔁 **~2.5× faster end-to-end workflows**
Benchmarks are:
* reproducible
* committed as raw JSON
* runnable locally via `bench/`
See [`Docs: Performance`](https://akhundmurad.github.io/typeid-python/performance/) for details.
## Installation
### Core
```console
$ pip install typeid-python
```
Included:
* Rust base32 encode/decode
* `uuid-utils` for fast UUIDv7 generation
### Other optional extras
```console
$ pip install typeid-python[yaml] # YAML schema support
$ pip install typeid-python[cli] # CLI tools
```
Extras are **strictly optional**.
## Usage
### Basic
```python
from typeid import TypeID
tid = TypeID(prefix="user")
assert tid.prefix == "user"
assert isinstance(tid.suffix, str)
assert str(tid).startswith("user_")
```
### From string
```python
from typeid import TypeID
tid = TypeID.from_string("user_01h45ytscbebyvny4gc8cr8ma2")
assert tid.prefix == "user"
```
### From UUIDv7
```python
from typeid import TypeID
from uuid_utils import uuid7
u = uuid7()
tid = TypeID.from_uuid(prefix="user", suffix=u)
assert tid.uuid.version == 7
```
### Typed prefixes
```python
from typing import Literal
from typeid import TypeID, typeid_factory
UserID = TypeID[Literal["user"]]
gen_user_id = typeid_factory("user")
user_id = gen_user_id()
```
## CLI
```console
$ pip install typeid-python[cli]
```
Generate:
```console
$ typeid new -p user
user_01h2xcejqtf2nbrexx3vqjhp41
```
Decode:
```console
$ typeid decode user_01h2xcejqtf2nbrexx3vqjhp41
uuid: 0188bac7-4afa-78aa-bc3b-bd1eef28d881
```
Encode:
```console
$ typeid encode 0188bac7-4afa-78aa-bc3b-bd1eef28d881 --prefix user
```
## ✨ `typeid explain` — understand any ID
```console
$ typeid explain user_01h45ytscbebyvny4gc8cr8ma2
```
Outputs:
```yaml
parsed:
prefix: user
uuid: 01890bf0-846f-7762-8605-5a3abb40e0e5
created_at: 2025-03-12T10:41:23Z
sortable: true
```
Works **without schema**, fully offline.
## Schema-based explanations
Define meaning for prefixes using JSON or YAML.
Example (`typeid.schema.json`):
```json
{
"schema_version": 1,
"types": {
"user": {
"name": "User",
"owner_team": "identity-platform",
"pii": true
}
}
}
```
Then:
```console
$ typeid explain user_01h45ytscbebyvny4gc8cr8ma2
```
Read more here: ["Docs: Explain"](https://akhundmurad.github.io/typeid-python/performance/).
## Design principles
* **Non-breaking**: stable APIs
* **Optional acceleration**: Rust is opt-in
* **Lazy evaluation**: work is done only when needed
* **Explainability**: identifiers carry meaning
* **Transparency**: performance claims are backed by data
> Think of TypeID as
> **UUIDs + semantics + observability — without sacrificing speed**
## License
MIT
typeid/__init__.py,sha256=YWaZ6tmmlnlFfNQO2NmrzlEW04yRCp54H8A-pRTdH1E,314
typeid/_base32.cpython-310-darwin.so,sha256=g-NS8BbilCnFDhHQie8IQQGhy-hf68XIXDoRXCnyEbY,487872
typeid/base32.py,sha256=74oJ1Xm3wHTBY1DqaIk53tVxmL3V6yTnFDuOK4mkbhM,210
typeid/cli.py,sha256=luCyGYbt0z1VhiCWcLVWaBspdOH8hWCHT0Kn1oznPk4,4159
typeid/constants.py,sha256=ua-JigETdE4pZvOB9ALK_71sDOZKzOYIabHlJQ01yAw,84
typeid/errors.py,sha256=2bSRH97Uvq_V1KnLadTmTNHAV5yOXOAHetJwz0YKDzc,225
typeid/explain/__init__.py,sha256=2kSFzI_l7F9cXUAN_JTJbu-1ID-TlgLYJBl9hjkRz-A,2141
typeid/explain/discovery.py,sha256=RKxebqLUqwQpHQp_nTO5PkK2-z8dejGHWtuw35VmAK8,3681
typeid/explain/engine.py,sha256=-cKThbazfdvSNb1YvJ8JZ0t3N9Z2av0ubwMEsW0y_Os,8023
typeid/explain/formatters.py,sha256=VAZGNGVKq52YS6ZjWPB28IGr_opiP676RSel95qV3iQ,6819
typeid/explain/model.py,sha256=pd-vqA6SAAnPV1l5_ZVbTqwXoRLELd0n_7tbNtg17L8,5086
typeid/explain/registry.py,sha256=DUQ6Jmk4M5la7Ye5BMXQMhqmDKjM36ohTUYx6ZRvjDo,6786
typeid/factory.py,sha256=UJzWN8djufyYQhR08GmXyGrKfWaGIUvPv1GIKKG5RJo,909
typeid/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
typeid/typeid.py,sha256=axWR9dSXJ0QHZclPFHshe-vS1OjWANPBXbFEpAcT-ro,10657
typeid/validation.py,sha256=0c2XWTkHro1gLaJmQnqW6XoSD1weSxWpBtEAbU157PI,1313
typeid_python-0.3.6.dist-info/METADATA,sha256=9PVkYLwbrT_jpKp-dodrsbD6ZnkqvP00T8YM4bC3m2g,5810
typeid_python-0.3.6.dist-info/WHEEL,sha256=IiUSfnZcnKtfg3tUHJ05sdhsIxnb0hSO-4fdRXTiMXo,105
typeid_python-0.3.6.dist-info/entry_points.txt,sha256=nnZGQ4ygTxWYd3Wq1MknTNFLN76MIxJ8FFRB54QVhGs,40
typeid_python-0.3.6.dist-info/licenses/LICENSE,sha256=f98oZ9FId4i3835UJYGw066BU8PSc57L1utGWS1ypcs,1070
typeid_python-0.3.6.dist-info/RECORD,,

Sorry, the diff of this file is not supported yet

Wheel-Version: 1.0
Generator: maturin (1.10.2)
Root-Is-Purelib: false
Tag: cp310-cp310-macosx_11_0_arm64