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
BeforeValidatorandAfterValidator - 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
iurnsas 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file international_urns-1.0.0rc2.tar.gz.
File metadata
- Download URL: international_urns-1.0.0rc2.tar.gz
- Upload date:
- Size: 7.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
010bd6b5e0e6b30ba2ad08aa1a4a6635b8f93fa9b8eb0a7ab9b885e741484d98
|
|
| MD5 |
e1cf0862695301e171e4d358f997ce87
|
|
| BLAKE2b-256 |
706f221989efa7d03ea1b9a0664350b038ee02ab3bc8d3a875060f72feb750be
|
File details
Details for the file international_urns-1.0.0rc2-py3-none-any.whl.
File metadata
- Download URL: international_urns-1.0.0rc2-py3-none-any.whl
- Upload date:
- Size: 9.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bb0afa36af60b7a16ed7692f6b981c340eb638d7fa8a77fb290c434bc3b15c3
|
|
| MD5 |
bbd639c117c6b1e1f0c98bd4162051a7
|
|
| BLAKE2b-256 |
49672f28de69f214ec9025a6b060d5272928a1379dd04c49002bfb2c64f45493
|