Skip to main content

A microkernel-based library for validating country-specific URN formats

Project description

International URNs

A microkernel-based Python library for validating country-specific URN (Uniform Resource Name) formats.

Overview

International URNs provides a pluggable architecture for validating URNs associated with countries using ISO 3166-1 Alpha-2 codes. The library uses a microkernel design where country-specific validators are provided by separate plugin packages.

URN Format: urn:country_code:document_type:document_value

Example: urn:es:dni:12345678X

Features

  • Microkernel Architecture: Core library provides the framework, plugins provide country-specific validation
  • Auto-registration: Validators automatically register themselves using Python's __init_subclass__
  • Entry Point Discovery: Plugins are discovered and loaded via Python entry points
  • ISO 3166-1 Alpha-2 Enforcement: Country codes are validated to be exactly 2 letters or "--" (wildcard)
  • Pydantic Integration: Seamless integration with Pydantic's BeforeValidator and AfterValidator
  • Case-Insensitive: URN scheme, country codes, and document types are case-insensitive (NSS remainder preserves case)
  • Type-Safe: Full type hints with mypy support
  • Extensible: Easy to add new country and document type validators

Installation

pip install international-urns

For development:

# Create virtual environment and install with test dependencies
uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
uv pip install -e ".[test]"

Usage

Note: Examples use iurns as an abbreviated import alias for convenience.

Basic Validation with Pydantic

from pydantic import BaseModel, AfterValidator, BeforeValidator
from typing import Annotated
import international_urns as iurns

class Document(BaseModel):
    urn: Annotated[
        str,
        BeforeValidator(iurns.create_normalizer()),
        AfterValidator(iurns.get_validator('es', 'dni'))
    ]

# Validates and normalizes the URN
doc = Document(urn="URN:ES:DNI:12345678X")
print(doc.urn)  # Output: "urn:es:dni:12345678X"

Normalization

URN normalization converts the scheme, country code, and document type to lowercase while preserving the case of the document value:

import international_urns as iurns

normalized = iurns.normalize_urn("URN:ES:DNI:12345678X")
print(normalized)  # Output: "urn:es:dni:12345678X"

Wildcard Validator

The library includes a built-in wildcard validator that accepts any URN matching the pattern urn:--:--:...:

import international_urns as iurns

validator = iurns.get_validator('--', '--')
result = validator('urn:--:--:anything')  # Valid

Registry Introspection

import international_urns as iurns

# List all available validators
validators = iurns.list_validators()
print(validators)  # [('--', '--'), ('es', 'dni'), ...]

# Check if a validator exists
if iurns.has_validator('es', 'dni'):
    validator = iurns.get_validator('es', 'dni')
    result = validator('urn:es:dni:12345678X')

Creating Plugins

To create a plugin for a new country or document type:

1. Create a new package

Example: international-urns-es for Spanish documents

2. Define validators

Subclass URNValidator and specify the country code (ISO 3166-1 Alpha-2) and document types:

from international_urns import URNValidator

class SpanishDNIValidator(URNValidator):
    country_code = "es"  # Must be 2 letters or "--"
    document_types = ["dni", "nie"]

    def validate(self, urn: str) -> str:
        # Implement validation logic
        # Raise ValueError if invalid
        # Return the URN (possibly normalized) if valid

        if not self._check_dni_format(urn):
            raise ValueError(f"Invalid DNI format: {urn}")

        return urn

    def _check_dni_format(self, urn: str) -> bool:
        # Custom validation logic here
        return True

3. Register via entry points

In your plugin's pyproject.toml:

[project.entry-points.'international_urns.plugins']
es = 'international_urns_es'

The validator will automatically register itself when the plugin is imported.

Development

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=international_urns --cov-report=html

# Run specific test file
pytest tests/test_registry.py

Linting and Type Checking

# Lint and format
ruff check .
ruff format .

# Type checking
mypy international_urns

Requirements

  • Python 3.11+
  • urnparse

License

MIT License - see LICENSE file for details

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

international_urns-1.0.0rc2.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

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

international_urns-1.0.0rc2-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file international_urns-1.0.0rc2.tar.gz.

File metadata

File hashes

Hashes for international_urns-1.0.0rc2.tar.gz
Algorithm Hash digest
SHA256 010bd6b5e0e6b30ba2ad08aa1a4a6635b8f93fa9b8eb0a7ab9b885e741484d98
MD5 e1cf0862695301e171e4d358f997ce87
BLAKE2b-256 706f221989efa7d03ea1b9a0664350b038ee02ab3bc8d3a875060f72feb750be

See more details on using hashes here.

File details

Details for the file international_urns-1.0.0rc2-py3-none-any.whl.

File metadata

File hashes

Hashes for international_urns-1.0.0rc2-py3-none-any.whl
Algorithm Hash digest
SHA256 1bb0afa36af60b7a16ed7692f6b981c340eb638d7fa8a77fb290c434bc3b15c3
MD5 bbd639c117c6b1e1f0c98bd4162051a7
BLAKE2b-256 49672f28de69f214ec9025a6b060d5272928a1379dd04c49002bfb2c64f45493

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