Skip to main content

Universal Prefixed Literal IDs - type-safe, human-readable identifiers

Project description

UPLID

Universal Prefixed Literal IDs - type-safe, human-readable identifiers for Python 3.14+.

CI PyPI Python

Features

  • Type-safe prefixes: UPLID[Literal["usr"]] prevents mixing user IDs with org IDs
  • Human-readable: usr_4mJ9k2L8nP3qR7sT1vW5xY (Stripe-style)
  • Time-sortable: Built on UUIDv7 for natural ordering
  • Compact: 22-character base62 encoding
  • Zero external deps: Uses Python 3.14's stdlib uuid7()
  • Pydantic 2 native: Full validation and serialization support

Installation

pip install uplid
# or
uv add uplid

Requires Python 3.14+.

Quick Start

from typing import Literal
from pydantic import BaseModel, Field
from uplid import UPLID, factory

# Define typed ID aliases
UserId = UPLID[Literal["usr"]]
OrgId = UPLID[Literal["org"]]

# Use in Pydantic models
class User(BaseModel):
    id: UserId = Field(default_factory=factory(UserId))
    org_id: OrgId

# Generate IDs
user_id = UPLID.generate("usr")
print(user_id)  # usr_4mJ9k2L8nP3qR7sT1vW5xY

# Parse from string
parsed = UPLID.from_string("usr_4mJ9k2L8nP3qR7sT1vW5xY", "usr")

# Type safety - these are compile-time errors with ty/mypy:
# user.org_id = user_id  # Error: UserId != OrgId

Prefix Rules

Prefixes must be snake_case:

  • Lowercase letters and underscores only
  • Cannot start or end with underscore
  • Examples: usr, api_key, org_member

API Reference

UPLID[PREFIX]

Generic class for prefixed IDs.

# Generate new ID
uid = UPLID.generate("usr")

# Parse from string
uid = UPLID.from_string("usr_abc123...", "usr")

# Properties
uid.prefix      # "usr"
uid.uid         # UUID object
uid.datetime    # datetime from UUIDv7
uid.timestamp   # float (Unix timestamp)
uid.base62_uid  # "abc123..." (22 chars)

factory(UPLIDType)

Creates a factory function for Pydantic's default_factory.

UserId = UPLID[Literal["usr"]]

class User(BaseModel):
    id: UserId = Field(default_factory=factory(UserId))

parse(UPLIDType)

Creates a parser function that raises UPLIDError on invalid input.

from uplid import UPLID, parse, UPLIDError

UserId = UPLID[Literal["usr"]]
parse_user_id = parse(UserId)

try:
    uid = parse_user_id("usr_abc123...")
except UPLIDError as e:
    print(e)

UPLIDType

Protocol for generic functions accepting any UPLID:

from uplid import UPLIDType

def log_entity(id: UPLIDType) -> None:
    print(f"{id.prefix} created at {id.datetime}")

UPLIDError

Exception raised for invalid IDs. Subclasses ValueError.

from uplid import UPLIDError

try:
    UPLID.from_string("invalid", "usr")
except UPLIDError as e:
    print(e)
except ValueError:  # Also works
    pass

License

MIT

Project details


Download files

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

Source Distribution

uplid-1.0.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uplid-1.0.0-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file uplid-1.0.0.tar.gz.

File metadata

  • Download URL: uplid-1.0.0.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for uplid-1.0.0.tar.gz
Algorithm Hash digest
SHA256 62a4da57542ec73257c1a099f1e78926838d6cf6d2fd5efc8640413a75b6d7bf
MD5 3f22c60e3dd0a04b0bf2fbc29b6d4e0a
BLAKE2b-256 540d85619524cbff250c1989b94bd9182a88248bfa05349b1d360ea243e26fb8

See more details on using hashes here.

File details

Details for the file uplid-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: uplid-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 7.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for uplid-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa5f24b1c6c95226c814fc6c9875b645ce1438f29c069d15a42794a8505bf65f
MD5 0ade0a7a40ee771e6d374d74414b61bc
BLAKE2b-256 23f0ca8ddd4d816cee4d1e42f80d43e9d6fa132ade4686baa888d30ca9a9fa15

See more details on using hashes here.

Supported by

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