RO-Crate Schema Library
A Pythonic library for creating and managing RO-Crates.
🚀 New to RO-Crate? Start with the Quick Start Guide!
What is it?
This library provides an interface for creating RO-Crates (Research Object Crates) a community standard for packaging research data with their metadata. Additionally to conventional crates, it allows to easily add objects of custom types (not present in Schema.org) and encode them as RDF according to the profile. The modules offers two interfaces to operate with crates:
- Pydantic models with decorators to declaratively define schemas that automatically generate RDF/OWL definitions.
- Pogrammatic builder-style interfaces for integration with other tooling or for working with objects whose schema isn't known at compile time.
Installation
From PyPI (recommended)
pip install lib-ro-crate-schema
From Source
git clone https://github.com/researchobjectschema/ro-crate-interoperability-profile.git
cd ro-crate-interoperability-profile/0.2.x/lib/python/lib-ro-crate-schema
pip install -e .
Quick Start
For complete working examples, see the examples/ directory:
- python_quickstart_write.py - Create and export an RO-Crate
- python_quickstart_read.py - Import and read an RO-Crate
- minimal_pydantic_example.py - Minimal Pydantic usage
- full_example.py - Complete export/import/modify workflow
Here's a minimal example of creating an RO-Crate with schema definitions:
from lib_ro_crate_schema import SchemaFacade, ro_crate_schema, Field
from pydantic import BaseModel
# Define your schema using decorators
@ro_crate_schema(ontology="https://schema.org/Person")
class Person(BaseModel):
name: str = Field(json_schema_extra={"ontology": "https://schema.org/name"})
email: str = Field(json_schema_extra={"ontology": "https://schema.org/email"})
# Create an instance
person = Person(name="Dr. Alice Smith", email="alice@example.com")
# Export to RO-Crate
facade = SchemaFacade()
facade.add_all_registered_models() # Register all @ro_crate_schema models
facade.add_model_instance(person, "person_001")
facade.write("my_research_crate")
This creates a complete RO-Crate with:
ro-crate-metadata.jsoncontaining your data and schema- Proper RDF/OWL definitions
- Schema.org ontology mappings
Key Features
✨ Pydantic Integration - Define schemas using familiar Pydantic models
📦 File Handling - Include data files alongside metadata
🔄 Round-trip Support - Import and re-export RO-Crates without data loss
🏷️ Ontology Mapping - Map to standard vocabularies (Schema.org, custom ontologies)
🔒 Type Safety - Strong typing with automatic validation
📊 RDF Export - Generate RDFS/OWL schema definitions
More Examples
Including Data Files
facade.add_file("experiment_data.csv", name="Experimental Results",
description="Raw data from chemical synthesis experiment")
facade.write("my_crate")
Complex Relationships
@ro_crate_schema(ontology="https://schema.org/Organization")
class Organization(BaseModel):
name: str = Field(json_schema_extra={"ontology": "https://schema.org/name"})
@ro_crate_schema(ontology="https://schema.org/Person")
class Person(BaseModel):
name: str = Field(json_schema_extra={"ontology": "https://schema.org/name"})
affiliation: Organization = Field(json_schema_extra={"ontology": "https://schema.org/affiliation"})
org = Organization(name="MIT")
person = Person(name="Alice", affiliation=org)
facade = SchemaFacade()
facade.add_all_registered_models()
facade.add_model_instance(org, "org_001")
facade.add_model_instance(person, "person_001")
facade.write("my_crate")
Importing Existing RO-Crates
from lib_ro_crate_schema import SchemaFacade
facade = SchemaFacade.from_ro_crate("path/to/existing_crate")
# Modify and re-export
facade.write("modified_crate")
Documentation
- Full Examples - Comprehensive examples including scientific workflows
- API Reference - Detailed API documentation
- Tests - Test suite demonstrating all features
Running Examples
# Simple decorator example
python examples/decorator_example.py
# Complex scientific workflow with file handling
python examples/full_example.py
# Import/export demonstration
python examples/minimal_import_example.py
Running Tests
# All tests
python run_all_tests.py
# Or with pytest
pytest tests/
Advanced Usage
Manual Construction (without decorators)
For fine-grained control, you can manually construct Type, TypeProperty, and MetadataEntry objects. This is useful for example when constructing objects from other schemas like SQL or JSON schemas, which don't immediately correspond to pydantic models. You can use it like this:
from lib_ro_crate_schema import SchemaFacade, Type, TypeProperty, MetadataEntry
# Create property definition
name_property = TypeProperty(
id="name",
range_includes=["http://www.w3.org/2001/XMLSchema#string"],
ontological_annotations=["https://schema.org/name"]
)
# Create type definition
person_type = Type(
id="Person",
ontological_annotations=["https://schema.org/Person"],
rdfs_property=[name_property]
)
# Create instance data
person_entry = MetadataEntry(
id="person_001",
class_id="Person",
properties={"name": "Alice"}
)
facade = SchemaFacade()
facade.addType(person_type)
facade.addEntry(person_entry)
facade.write("manual_crate")
See examples/python_quickstart_write.py for more details.
API Overview
Core Classes
| Class | Purpose |
|---|---|
SchemaFacade |
Main interface for creating and exporting RO-Crates |
Type |
Define RDFS classes (schema types) |
TypeProperty |
Define RDF properties for types |
MetadataEntry |
Instance data conforming to a Type |
Restriction |
OWL cardinality and property restrictions |
Decorators (Recommended)
| Decorator | Purpose |
|---|---|
@ro_crate_schema |
Mark Pydantic model as RO-Crate schema type |
Field |
Enhanced Pydantic Field with ontology mapping |
SchemaFacade Methods
facade = SchemaFacade()
# Decorator API
facade.add_all_registered_models() # Add all @ro_crate_schema models
facade.add_model_instance(instance, id) # Add Pydantic instance
# Manual API
facade.addType(type_obj) # Add Type definition
facade.addEntry(entry) # Add MetadataEntry
# File handling
facade.add_file(path, name, description) # Include data file
# Export
facade.write(destination) # Write complete RO-Crate
facade.to_graph() # Get RDFLib Graph
# Import
SchemaFacade.from_ro_crate(path) # Load existing RO-Crate
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Citation
If you use this library in your research, please cite:
@software{ro_crate_schema,
title = {RO-Crate Schema Library},
author = {Baffelli, Simone and Su, Pascal},
year = {2025},
url = {https://github.com/researchobjectschema/ro-crate-interoperability-profile}
}
Documentation
- README.md - Installation and quick start
- TECHNICAL.md - Architecture, components, and API reference
- PUBLISHING.md - Guide for publishing to PyPI
- examples/ - Working code examples
Links
- Repository: https://github.com/researchobjectschema/ro-crate-interoperability-profile
- RO-Crate Specification: https://www.researchobject.org/ro-crate/
- Pydantic Documentation: https://docs.pydantic.dev/