Python library for validating Digital Product Passports (DPP) according to EU ESPR regulations and CIRPASS/UNECE ontologies
Project description
dppvalidator
The open-source compliance engine for EU Digital Product Passports
Installation • Quick Start • Features • Documentation • Contributing
dppvalidator is a Python library for validating Digital Product Passports (DPP) according to EU ESPR regulations and UNTP standards.
Starting 2027, every textile and apparel product sold in the EU must have a Digital Product Passport. This library ensures your DPP data is compliant before it hits production — saving fashion brands from costly compliance failures and enabling seamless integration with the circular economy.
Why dppvalidator?
| Challenge | Solution |
|---|---|
| Complex JSON Schema validation | Five-layer validation catches errors at schema, model, JSON-LD, semantic, and cryptographic levels |
| Evolving UNTP specifications | Built-in schema support for UNTP DPP 0.6.1 with easy version switching |
| Integration with existing systems | CLI + Python API for pipelines, CI/CD, and application integration |
| Custom business rules | Plugin system for domain-specific validators and exporters |
| Interoperability requirements | JSON-LD export for W3C Verifiable Credentials compliance |
Installation
# Using uv (recommended)
uv add dppvalidator
# Using pip
pip install dppvalidator
# With CLI extras (rich formatting)
pip install dppvalidator[cli]
Requirements: Python 3.10+
Quick Start
Validate a DPP
from dppvalidator.validators import ValidationEngine
engine = ValidationEngine()
result = engine.validate(
{
"id": "https://example.com/dpp/battery-001",
"type": ["DigitalProductPassport", "VerifiableCredential"],
"issuer": {
"id": "https://example.com/manufacturer",
"name": "Acme Battery Co.",
},
"credentialSubject": {
"id": "https://example.com/product/battery-001",
"product": {
"name": "EV Battery Pack",
"description": "High-capacity lithium-ion battery",
},
},
}
)
if result.valid:
print(f"✓ Valid in {result.validation_time_ms:.2f}ms")
else:
for error in result.errors:
print(f"✗ [{error.code}] {error.path}: {error.message}")
Command Line
# Validate a DPP file
dppvalidator validate passport.json
# Strict mode - warnings become errors
dppvalidator validate passport.json --strict
# Export to JSON-LD (W3C Verifiable Credential format)
dppvalidator export passport.json --format jsonld --output passport.jsonld
# Display schema information
dppvalidator schema --version 0.6.1
Export to JSON-LD
from dppvalidator.models import DigitalProductPassport, CredentialIssuer
from dppvalidator.exporters import JSONLDExporter
passport = DigitalProductPassport(
id="https://example.com/dpp/product-001",
issuer=CredentialIssuer(
id="https://example.com/issuer", name="Sustainable Textiles Ltd."
),
)
exporter = JSONLDExporter()
jsonld_output = exporter.export(passport)
# Ready for W3C Verifiable Credentials ecosystem
Features
Five-Layer Validation Architecture
flowchart TD
subgraph Input
A[/"📄 Input Data (JSON)"/]
end
subgraph Layer0["Layer 0: Schema Detection"]
A0["Auto-detect schema version<br/>from $schema, @context, type"]
end
subgraph Layer1["Layer 1: Schema Validation"]
B["JSON Schema Draft 2020-12<br/>Required fields, types, formats"]
end
subgraph Layer2["Layer 2: Model Validation"]
C["Pydantic v2 Models<br/>Type coercion, URL validation"]
end
subgraph Layer3["Layer 3: JSON-LD Semantic"]
C2["PyLD Expansion<br/>Context resolution, term validation"]
end
subgraph Layer4["Layer 4: Business Logic"]
D["Business Rules & Vocabularies<br/>ISO codes, date logic, GTIN checksums"]
end
subgraph Layer5["Layer 5: Cryptographic"]
E["VC Signature Verification<br/>DID resolution, Ed25519/ECDSA"]
end
subgraph Output
F[/"✅ ValidationResult<br/>.valid | .errors | .signature_valid"/]
end
A --> A0
A0 --> B
B -->|"SCH001-SCH099"| C
C -->|"MOD001-MOD099"| C2
C2 -->|"JLD001-JLD099"| D
D -->|"SEM001-SEM099"| E
E -->|"SIG001-SIG099"| F
Selective Layer Validation
from dppvalidator.validators import ValidationEngine
# Run all layers (default)
engine = ValidationEngine()
# Schema validation only (fastest)
engine = ValidationEngine(layers=["schema"])
# Skip schema, run model + semantic
engine = ValidationEngine(layers=["model", "semantic"])
# Enable JSON-LD validation
engine = ValidationEngine(validate_jsonld=True)
# Enable signature verification
engine = ValidationEngine(verify_signatures=True)
result = engine.validate(dpp_data)
if result.signature_valid:
print(f"Signed by: {result.issuer_did}")
Performance
| Layer | Mean Time | Throughput |
|---|---|---|
| Model (minimal) | 0.011ms | 86,988 ops/sec |
| Model (full) | 0.016ms | 61,848 ops/sec |
| Semantic | 0.005ms | 193,628 ops/sec |
| Full (Model+Sem) | 0.017ms | 58,177 ops/sec |
| Engine Creation | 3.867ms | 259 ops/sec |
Benchmarked on Apple Silicon. JSON-LD and signature verification depend on network latency (cached after first request).
Plugin System
Extend dppvalidator with custom validators following the SemanticRule protocol:
from dppvalidator.plugins import PluginRegistry
# Create a custom validator implementing SemanticRule protocol
class TextileFiberRule:
"""Custom rule to validate textile fiber composition."""
rule_id = "TEX001"
description = "Fiber composition must sum to 100%"
severity = "error"
suggestion = "Ensure all fiber percentages add up to 100"
docs_url = "https://example.com/textile-rules"
def check(self, passport):
"""Return list of (json_path, error_message) tuples."""
violations = []
# Add your validation logic here
return violations
# Register with the plugin registry
registry = PluginRegistry(auto_discover=False)
registry.register_validator("textile", TextileFiberRule)
# ValidationEngine auto-discovers plugins via entry points by default
engine = ValidationEngine(load_plugins=True)
Documentation
📚 Full documentation: artiso-ai.github.io/dppvalidator
| Guide | Description |
|---|---|
| Installation | Setup and CLI extras |
| Quick Start | Get started in 5 minutes |
| CLI Reference | Command-line interface |
| Validation Layers | Understanding the five-layer architecture |
| API Reference | Complete Python API |
Built for Fashion & Textiles
The EU's Ecodesign for Sustainable Products Regulation (ESPR) mandates Digital Product Passports for textiles starting 2027. dppvalidator helps fashion brands prepare now:
| DPP Requirement | How dppvalidator Helps |
|---|---|
| Material composition & weights | Validates fiber percentages sum to 100% |
| Manufacturing processes | Validates supply chain node structure |
| Environmental indicators | Supports LCA data validation |
| Chemical compliance (REACH) | Semantic validation for substance references |
| Traceability information | Validates production stage URIs |
| Durability & recyclability | Custom validators via plugin system |
Use Cases
dppvalidator serves diverse stakeholders across the product lifecycle:
| Use Case | Target User | Value Proposition |
|---|---|---|
| Pre-production validation | Brand product teams | Catch errors before QR code generation |
| Supplier onboarding | Procurement teams | Validate supplier DPP submissions |
| CI/CD compliance gates | DevOps teams | Automated compliance checks in pipelines |
| Data migration | IT teams | Validate legacy data exports to DPP format |
| Consumer apps | App developers | DPP scanning, parsing, and display |
| Recycling facilities | Waste management | Material identification for sorting |
| Resale platforms | Recommerce | Product authentication and history |
| Customs & compliance | Border control | Import compliance verification |
Example: CI/CD Integration
# .github/workflows/validate-dpp.yml
- name: Validate DPP files
run: dppvalidator validate data/passports/*.json --strict
Example: Supplier Validation API
from dppvalidator.validators import ValidationEngine
engine = ValidationEngine(strict_mode=True)
def validate_supplier_submission(dpp_json: dict) -> bool:
result = engine.validate(dpp_json)
if not result.valid:
raise ValueError(f"Invalid DPP: {result.errors}")
return True
Related Standards
- UNTP Digital Product Passport — UN/CEFACT specification
- EU ESPR Regulation — Ecodesign for Sustainable Products
- W3C Verifiable Credentials — Credential format standard
⚠️ Note on UNTP Specification: The UNTP Digital Product Passport specification is under active development and not yet ready for production implementation. We track the latest maintained releases and will update dppvalidator as the specification stabilizes. See the UNTP releases page for current status.
Contributing
We welcome contributions! Here's how to get started:
# Clone the repository
git clone https://github.com/artiso-ai/dppvalidator.git
cd dppvalidator
# Install dependencies with uv
uv sync --all-extras
# Run tests
uv run pytest
# Run linting
uv run ruff check .
See our Contributing Guide for more details.
About ARTISO
|
dppvalidator is developed and maintained by ARTISO, a Barcelona-based fashion technology company. |
|
We believe the fashion industry's transition to sustainability requires open, accessible tools. By open-sourcing dppvalidator, we're enabling brands of all sizes - from emerging designers to global retailers - to meet EU compliance requirements without proprietary solutions.
Our commitment:
- Open Source First - Core validation engine will always be free and MIT-licensed
- Fashion Expertise - Built by a team with deep industry experience at major brands
- Circular Economy - Enabling the data infrastructure for textile recycling and resale
- Community Driven - We welcome contributions from brands, sustainability experts, and developers
"The circular economy can only work if recyclers can read the tags. dppvalidator ensures interoperability across the entire fashion supply chain."
License
MIT License — see LICENSE for details.
artiso.ai · Documentation · Issues
Built with ❤️ in Barcelona for a more sustainable fashion industry
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 dppvalidator-0.2.4.tar.gz.
File metadata
- Download URL: dppvalidator-0.2.4.tar.gz
- Upload date:
- Size: 1.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0064457f8101bd28eac306f1dc71e90c90c9c9f058ae28001226f70b21aa6ee3
|
|
| MD5 |
df703781ef090574dd534818f229bf81
|
|
| BLAKE2b-256 |
8785e46884411c6de343ddef1f6d838baa336759354e5fcf50bf1d801e7d3edf
|
Provenance
The following attestation bundles were made for dppvalidator-0.2.4.tar.gz:
Publisher:
release.yml on artiso-ai/dppvalidator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dppvalidator-0.2.4.tar.gz -
Subject digest:
0064457f8101bd28eac306f1dc71e90c90c9c9f058ae28001226f70b21aa6ee3 - Sigstore transparency entry: 886293054
- Sigstore integration time:
-
Permalink:
artiso-ai/dppvalidator@2f6766a7bf77ad9465aa314a42989ba5ee658f5d -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/artiso-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2f6766a7bf77ad9465aa314a42989ba5ee658f5d -
Trigger Event:
push
-
Statement type:
File details
Details for the file dppvalidator-0.2.4-py3-none-any.whl.
File metadata
- Download URL: dppvalidator-0.2.4-py3-none-any.whl
- Upload date:
- Size: 114.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74dfd792289f7e83d72a252c2db1a0a0fa548e5a98abfb327cb92df5612f602a
|
|
| MD5 |
c4973cae27524cccdf6184292fedf279
|
|
| BLAKE2b-256 |
271ef976c7975b5309f23973dea0d51bcff71e26ea3cdd7d73bc13c960a12b79
|
Provenance
The following attestation bundles were made for dppvalidator-0.2.4-py3-none-any.whl:
Publisher:
release.yml on artiso-ai/dppvalidator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dppvalidator-0.2.4-py3-none-any.whl -
Subject digest:
74dfd792289f7e83d72a252c2db1a0a0fa548e5a98abfb327cb92df5612f602a - Sigstore transparency entry: 886293056
- Sigstore integration time:
-
Permalink:
artiso-ai/dppvalidator@2f6766a7bf77ad9465aa314a42989ba5ee658f5d -
Branch / Tag:
refs/tags/v0.2.4 - Owner: https://github.com/artiso-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2f6766a7bf77ad9465aa314a42989ba5ee658f5d -
Trigger Event:
push
-
Statement type: