Python bindings for the shifty SHACL engine
Project description
shifty
A formalism-first SHACL validation and SHACL-AF inference engine written in Rust, grounded in the algebraic treatment of Common Foundations for SHACL, ShEx, and PG-Schema (arXiv:2502.01295). Available as a command-line tool and as Python bindings (pyshifty).
Features
- Full SHACL Core validation — node and property shapes, all standard constraint components
- SHACL-AF inference — forward-chaining
sh:ruleevaluation (Triple Rules, SPARQL Construct Rules) to a fixed point, with stratification analysis for recursive rulesets - Algebraic IR — shapes are lowered to a path algebra (π) and shape grammar (φ) before evaluation; the same IR drives both validation and inference
- Native SPARQL execution — a subset of
sh:sparqlconstraints and SPARQL Construct rules runs directly over an indexed dataset without a full SPARQL engine, with automatic fallback to Spareval for unsupported constructs - Multi-layer pipeline — parsing → algebraic lowering → normalization/CSE → physical planning → execution; each layer is independently inspectable
- pyshifty-compatible Python API —
validate()returns(conforms, report_graph, results_text)matching pyshifty's interface
Installation
CLI
cargo install --path crates/shifty-cli
Or build from source:
cargo build --release -p shifty-cli
# binary at target/release/shifty
Python
pip install pyshifty
The package installs as pyshifty but is imported as shifty:
import shifty
To build from source (requires Rust and maturin):
cd python
pip install maturin
maturin develop
CLI usage
Validate
shifty validate --shapes shapes.ttl --data data.ttl
conforms: false
violations: 1
<http://example.org/bob> [target: ∃ rdf:type .⊤]
- (ex:name) 123 → expected datatype xsd:string
Emit a W3C sh:ValidationReport in Turtle:
shifty validate --shapes shapes.ttl --data data.ttl --report
JSON output:
shifty validate --shapes shapes.ttl --data data.ttl --format json
Graph mode controls which triples are visible to path traversal and SPARQL evaluation:
# default: focus nodes from data; paths/SPARQL use data ∪ shapes
shifty validate --shapes shapes.ttl --data data.ttl --graph-mode union
# focus nodes and evaluation use data only
shifty validate --shapes shapes.ttl --data data.ttl --graph-mode data
# focus nodes and evaluation both use data ∪ shapes
shifty validate --shapes shapes.ttl --data data.ttl --graph-mode union-all
Infer
Run SHACL-AF rules to a fixed point, then print the derived triples:
shifty infer --shapes rules.ttl --data data.ttl
inferred 3 triple(s):
<http://example.org/r1> <http://example.org/area> "6"^^<http://www.w3.org/2001/XMLSchema#integer>
...
Inspect
Inspect how a shapes graph looks at each stage of the pipeline:
# Raw triples after parsing
shifty inspect --stage rdf shapes.ttl
# Lowered algebraic IR (φ/π notation)
shifty inspect --stage algebra shapes.ttl
# After normalization and common-subexpression elimination
shifty inspect --stage normalized shapes.ttl
# Stratification analysis (recursion detection)
shifty inspect --stage strata shapes.ttl
# Physical plan: focus sources + cost-ordered shape checks
shifty inspect --stage plan shapes.ttl
# SPARQL constraint capability: which queries run native vs. Spareval
shifty inspect --stage capability shapes.ttl
All stages support --format text (default), --format json; the algebra and normalized stages also support --format dot for Graphviz output.
Shapes files and data files may be local paths or HTTP/HTTPS URLs. Both --shapes and --data are repeatable to merge multiple files.
Python usage
import shifty
Validate (pyshifty-compatible)
shapes = """
@prefix sh: <http://www.w3.org/ns/shifty#> .
@prefix ex: <http://example.org/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:PersonShape a sh:NodeShape ;
sh:targetClass ex:Person ;
sh:property [
sh:path ex:name ;
sh:minCount 1 ;
sh:datatype xsd:string ;
] ;
sh:property [
sh:path ex:age ;
sh:maxCount 1 ;
sh:datatype xsd:integer ;
] .
"""
data = """
@prefix ex: <http://example.org/> .
ex:Alice a ex:Person ; ex:name "Alice" ; ex:age 30 .
ex:Bob a ex:Person .
"""
conforms, report_graph, results_text = shifty.validate(data, shapes)
# conforms → False
# report_graph → rdflib.Graph with sh:ValidationReport
# results_text → human-readable summary
Graph inputs can be a string, bytes, pathlib.Path, or rdflib.Graph. If shacl_graph is omitted, shapes are expected to be embedded in the data graph.
Validate with structured result
validate_algebra returns an AlgebraResult with typed Violation objects instead of an RDF report graph:
result = shifty.validate_algebra(data, shapes)
print(result.conforms) # False
for v in result.violations:
print(v.focus) # IRI of the failing focus node
for r in v.reasons:
print(r.message) # human-readable failure description
print(r.path) # path that was checked, if applicable
print(r.value) # the offending value node
Infer
Run SHACL-AF rules to a fixed point:
rules = """
@prefix sh: <http://www.w3.org/ns/shifty#> .
@prefix ex: <http://example.org/> .
ex:RectangleShape a sh:NodeShape ;
sh:targetClass ex:Rectangle ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate ex:area ;
sh:object [ sh:path ex:width ] ;
] .
"""
data = """
@prefix ex: <http://example.org/> .
ex:r1 a ex:Rectangle ; ex:width 3 ; ex:height 2 .
"""
result = shifty.infer(data, rules)
print(result.inferred_count) # number of newly derived triples
g = result.graph() # rdflib.Graph with original + inferred data
graph_mode
All three functions accept a graph_mode keyword argument:
shifty.validate(data, shapes, graph_mode="union") # default
shifty.validate(data, shapes, graph_mode="data")
shifty.validate(data, shapes, graph_mode="union-all")
File inputs
import pathlib
conforms, report, text = shifty.validate(
pathlib.Path("data.ttl"),
pathlib.Path("shapes.ttl"),
)
Crate structure
| crate | role |
|---|---|
shifty-algebra |
path algebra π, shape grammar φ, schema arena, rendering |
shifty-parse |
Turtle/RDF → algebraic IR lowering |
shifty-opt |
normalization, stratification, physical planning, native SPARQL lowering |
shifty-engine |
validation + AF inference execution, SPARQL executor |
shifty-cli |
shifty binary |
pyshifty (python/) |
PyO3 bindings, published as pyshifty on PyPI |
Design docs
The docs/ directory contains the full design:
docs/00-formalism.md— path algebra π, shape grammar φ, selectors, reference semanticsdocs/01-gap-analysis.md— W3C SHACL/SHACL-AF coverage and known gapsdocs/02-roadmap.md— layered build plan (Layer 0 → 7)
License
BSD-3-Clause
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 Distributions
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 pyshifty-0.1.2.tar.gz.
File metadata
- Download URL: pyshifty-0.1.2.tar.gz
- Upload date:
- Size: 186.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db0e5d40faca08a9b923bbafc7d74d183e7bdda1f65ffd1fabb83fb8f407b816
|
|
| MD5 |
b83ac5c15e13d50654cee555f4431151
|
|
| BLAKE2b-256 |
6eb482faec44ec5132e26d4f7a47ab11b05014c259c30c1eecfe4af995b963da
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2.tar.gz:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2.tar.gz -
Subject digest:
db0e5d40faca08a9b923bbafc7d74d183e7bdda1f65ffd1fabb83fb8f407b816 - Sigstore transparency entry: 1794304462
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyshifty-0.1.2-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: pyshifty-0.1.2-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89d059220c3af488505633f1d37714e2fa1e6a8aaf9e45bacefcf3cd5706452c
|
|
| MD5 |
25161a7c04562ea56c253f03ff3cb1ce
|
|
| BLAKE2b-256 |
d980590b9d10b8400ea083f2f219855680f6a57e89dd51656f1f98dacbf3c00c
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2-cp39-abi3-win_amd64.whl:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2-cp39-abi3-win_amd64.whl -
Subject digest:
89d059220c3af488505633f1d37714e2fa1e6a8aaf9e45bacefcf3cd5706452c - Sigstore transparency entry: 1794304946
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyshifty-0.1.2-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyshifty-0.1.2-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 29.1 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d47d796c4958e8297193d29ac14cc1ae6e3f2aeab8ed7b8310b04d68145c48c3
|
|
| MD5 |
1ec5972be8f7e2e665b59d9fbd3f5dd5
|
|
| BLAKE2b-256 |
90b81427845e87d141a2af347d2d1a2cb20a9e69f75bef155c3182dc3a31562f
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2-cp39-abi3-musllinux_1_2_x86_64.whl:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2-cp39-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
d47d796c4958e8297193d29ac14cc1ae6e3f2aeab8ed7b8310b04d68145c48c3 - Sigstore transparency entry: 1794305421
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyshifty-0.1.2-cp39-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: pyshifty-0.1.2-cp39-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 28.7 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0277aff7338b6fde0af8d9f310929baf482891239d4396f604acdce1752ccb96
|
|
| MD5 |
f007a5e226f729f075b5a0b3798366e3
|
|
| BLAKE2b-256 |
d57032c9bcf57d2bbd8cbf494de3e4b6dce493962be5ac11eaf3788a7e94e4ab
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2-cp39-abi3-musllinux_1_2_aarch64.whl:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2-cp39-abi3-musllinux_1_2_aarch64.whl -
Subject digest:
0277aff7338b6fde0af8d9f310929baf482891239d4396f604acdce1752ccb96 - Sigstore transparency entry: 1794304635
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyshifty-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyshifty-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 29.1 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
202c8f4a0132b33ed4739a0a8e0f3997362caff89d41bfdac4bec45fc0737fe6
|
|
| MD5 |
f8e10249e3e67cf8fee4d76902cb6e96
|
|
| BLAKE2b-256 |
2d2ec3a016f17ebbc84abf7d9d6dea9c5a4144a228a23df85a86b0fed36bb51c
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
202c8f4a0132b33ed4739a0a8e0f3997362caff89d41bfdac4bec45fc0737fe6 - Sigstore transparency entry: 1794304739
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyshifty-0.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pyshifty-0.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 28.7 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0d4de484e0067b0282326fe3e1c24d57246f3078a3a7f6a21a1b37ea652a006
|
|
| MD5 |
a73892ceb2d7c725bdab298f26024284
|
|
| BLAKE2b-256 |
5a505d702b7f8d7dc638ba179de7f1b1eab4326623d48c62522a2bdc9e54fd4c
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
f0d4de484e0067b0282326fe3e1c24d57246f3078a3a7f6a21a1b37ea652a006 - Sigstore transparency entry: 1794305121
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pyshifty-0.1.2-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyshifty-0.1.2-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.7 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68eeb249811373727858a6931a94f2f105b85a1f2918e57850affc580717f184
|
|
| MD5 |
855503647c297a451e0cc0b155986e26
|
|
| BLAKE2b-256 |
a4cab366cbd7e9e84bf3d8623e58b197c34efb0d4c140a6838de0369d4919acb
|
Provenance
The following attestation bundles were made for pyshifty-0.1.2-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on gtfierro/shifty
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyshifty-0.1.2-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
68eeb249811373727858a6931a94f2f105b85a1f2918e57850affc580717f184 - Sigstore transparency entry: 1794305294
- Sigstore integration time:
-
Permalink:
gtfierro/shifty@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/gtfierro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cc3c1b5cdf5b71ff7d501e3734ab1bc9317d0a90 -
Trigger Event:
push
-
Statement type: