Skip to main content

Generate, validate, and normalize rettX IDs for the Rett Syndrome Europe ecosystem

Project description

🧬 rettxid — RettX Patient Identifier Library

CI PyPI version Python 3.11+ License: MIT

rettxid is the official Python library for generating and validating rettX IDs, the pseudonymous, GDPR-safe identifiers used across the rettX European Rett Syndrome Patient Registry.

A rettX ID is a stable, globally unique, non-PII, human-friendly identifier assigned to each patient record. It enables:

  • safe cross-border data harmonization
  • pseudonymous linking of datasets
  • interoperability between registries, clinicians, and research groups
  • QR-based emergency and verification workflows
  • long-term governance for Rett Syndrome data in Europe

This repository contains the canonical reference implementation of the rettX ID format and generation rules.

Important: This library is stateless. It does not store rettX IDs or patient information.
Persistence and API endpoints are implemented in rettxapi.


✨ Features

  • Pure Python implementation (Python 3.11+)
  • Zero runtime dependencies (stdlib only)
  • Cryptographically secure ID generation using secrets module
  • Strict format validation with pre-compiled regex
  • Input normalization (handles case variations, whitespace, missing dashes)
  • Ambiguity-safe alphabet (excludes 0, 1, I, L, O, S)
  • Full type annotations (PEP 561 compliant)
  • 95%+ test coverage with property-based testing
  • Designed for integration with rettxapi and other rettX services

📦 Installation

Once published to PyPI:

pip install rettxid

Or install directly from GitHub:

pip install git+https://github.com/rett-europe/rettxid.git

For development:

git clone https://github.com/rett-europe/rettxid.git
cd rettxid
python -m venv .venv
.venv\Scripts\activate  # Windows
# source .venv/bin/activate  # Linux/Mac
pip install -e ".[dev]"

🚀 Usage

Generate a New rettX ID

from rettxid import generate_rettx_id

# Generate a new cryptographically random rettX ID
rid = generate_rettx_id()
print(rid)  
# → rettx-8GZ4-MK3P-2Q9A

Validate Format

from rettxid import validate_format

# Check if a string is a valid rettX ID format
validate_format("rettx-8GZ4-MK3P-2Q9A")  # → True
validate_format("rettx-8gz4-mk3p-2q9a")  # → False (lowercase body)
validate_format("invalid")               # → False
validate_format(None)                    # → False (doesn't raise)

Normalize User Input

from rettxid import normalize

# Convert various input formats to canonical form
normalize("rettx-8gz4-mk3p-2q9a")     # → "rettx-8GZ4-MK3P-2Q9A"
normalize("RETTX-8GZ4-MK3P-2Q9A")     # → "rettx-8GZ4-MK3P-2Q9A"
normalize("rettx8GZ4MK3P2Q9A")        # → "rettx-8GZ4-MK3P-2Q9A"
normalize("  rettx-8GZ4-MK3P-2Q9A  ") # → "rettx-8GZ4-MK3P-2Q9A"

# Raises ValueError for invalid input
normalize("invalid")  # → ValueError: Invalid rettX ID: 'invalid'

# Raises TypeError for non-string input  
normalize(None)       # → TypeError

📋 API Reference

generate_rettx_id() -> str

Generate a new cryptographically random rettX ID.

  • Returns: A valid rettX ID in format rettx-XXXX-XXXX-XXXX
  • Raises: RuntimeError if system entropy is unavailable (rare)

validate_format(id: str) -> bool

Check if a string matches the rettX ID v1 format.

  • Parameters: id — The string to validate
  • Returns: True if valid format, False otherwise
  • Note: Never raises; returns False for any invalid input including non-strings

normalize(id: str) -> str

Normalize a string into canonical rettX ID form.

  • Parameters: id — The string to normalize
  • Returns: The canonical rettX ID
  • Raises:
    • ValueError if input cannot be normalized
    • TypeError if input is not a string

🔐 Format Specification

The rettX ID v1 format:

rettx-XXXX-XXXX-XXXX
  • Prefix: rettx- (6 characters, always lowercase)
  • Body: 3 groups of 4 characters, separated by dashes
  • Alphabet: 30 ambiguity-safe characters: 23456789ABCDEFGHJKMNPQRTUVWXYZ
  • Excluded: 0 (zero), 1 (one), I, L, O, S (visually confusable)
  • Total length: 20 characters
  • Entropy: ~59 bits (collision probability < 1 in 30 million at 100K scale)

🔗 Integration with rettxapi

This library:

  • Generates rettX IDs
  • Validates rettX ID format
  • Normalizes user input

The rettxapi backend:

  • Stores rettx_id inside patient documents
  • Ensures uniqueness
  • Provides public & internal API endpoints
  • Generates QR codes for rettX SOS
  • Handles authentication, authorization, and audit logging

🧪 Testing

Run tests with:

pytest

Run with coverage:

pytest --cov=rettxid --cov-report=term-missing

Run type checking:

mypy src/rettxid --strict

Run linting:

ruff check src/rettxid tests

🗺️ Roadmap

  • v1: ✅ Initial ID format definition and reference implementation
  • v2: Optional checksum support
  • v3: Backward-compatible decoding/format transitions
  • Governance specification for rettX ID lifecycle
  • Language bindings (Rust, TypeScript)

🤝 Contributing

Contributions are welcome! Please open an issue or PR.


📄 License

This project is licensed under the MIT License, a permissive open-source license ideal for libraries intended to be reused across registries, research tools, and backend services. See LICENSE for details.


❤️ About Rett Syndrome Europe

This project is maintained by Rett Syndrome Europe (RSE) as part of the rettX ecosystem — a pan-European effort to build harmonized, high-quality patient data infrastructure to support research, clinical care, and family empowerment.

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

rettxid-1.0.0.tar.gz (73.6 kB view details)

Uploaded Source

Built Distribution

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

rettxid-1.0.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: rettxid-1.0.0.tar.gz
  • Upload date:
  • Size: 73.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rettxid-1.0.0.tar.gz
Algorithm Hash digest
SHA256 1ea6248b932772a7098a97d79244cc7781d0aafffa6c71fc8e6d99d896985de6
MD5 9df98bb0817c1632ebf0641059b763e4
BLAKE2b-256 231cf94e324f386de7494bc4fa406463188c5ab69da8b93842da38a95f87ca8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rettxid-1.0.0.tar.gz:

Publisher: publish.yml on rett-europe/rettxid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: rettxid-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rettxid-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2b19fee8fbd6c8109ce439bf9e0cb2a5c9f6cba4bc5bc2ed38070b164cea3647
MD5 f664ee7a174844ea2fc81313f2c28d68
BLAKE2b-256 6a61cf443d301f0eba97e9140dd5553db8b0bfc937838fea252537fb46a769f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for rettxid-1.0.0-py3-none-any.whl:

Publisher: publish.yml on rett-europe/rettxid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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