Pre-execution SPARQL query validator (SQV): syntactic and semantic validation against OWL ontologies and SHACL shapes.
Project description
sparql-validator
Pre-execution SPARQL query validation - a Python implementation of the SQV (SPARQL Query Validation) algorithm.
SQV catches typing errors, ontology-range mismatches, constraining-facet violations, and object-property-axiom breaches before a SPARQL query hits your triplestore - so you spend milliseconds on validation instead of seconds on an execution that was going to fail (or worse, silently return nothing).
Install
uv add sparql-validator
# or
pip install sparql-validator
30-second example
from sparql_validator import SPARQLValidator
validator = SPARQLValidator.from_files(
ontology="tests/fixtures/film.ttl",
shapes="tests/fixtures/film.shacl.ttl", # optional - see below
)
query = """
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?x WHERE {
?x dbo:birthDate "1974-11-11"^^xsd:char . # xsd:char is not W3C
}
"""
report = validator.validate(query)
if report: # ValidationReport is truthy iff ok
print("Query is valid.")
else:
for err in report: # iterable of ValidationError
print(err)
# [datatype] Datatype 'xsd:char' is not recommended by the W3C.
# - hint: Use one of xsd:string, xsd:integer, xsd:date, ...
SHACL shapes are optional
The shapes argument to SPARQLValidator.from_files (and the --shapes
CLI flag) is optional. What that means for validation:
shapes provided |
shapes omitted |
|
|---|---|---|
| Query decomposition | run | run |
| Datatype / range / lexical form / facet checks (syntactic) | run | run |
| RDF data-graph generation | run | run |
| SHACL conformance (semantic axioms: functional, inverse-functional, symmetric, asymmetric, ...) | run | skipped |
When no shapes graph is supplied the validator behaves as a purely
syntactic validator: every ErrorKind in the table below is still detected
except OBJECT_AXIOM, which can only surface via SHACL.
Skip shapes when you don't yet have a shapes graph (they have to be
authored separately from the ontology), when you only care about the
syntactic checks, or when the semantic rules for your ontology are not
expressible as SHACL constraints.
# Purely syntactic validator - no SHACL shapes.
validator = SPARQLValidator.from_files(ontology="film.ttl")
# CLI equivalent: leave --shapes off.
sparql-validator --ontology film.ttl --query @path/to/query.rq
Command line
sparql-validator \
--ontology tests/fixtures/film.ttl \
--shapes tests/fixtures/film.shacl.ttl \
--query @path/to/query.rq \
--json
Exit code: 0 valid, 1 invalid, 2 I/O or malformed-query error.
What SQV checks for you
| Category | Example defect | Kind |
|---|---|---|
| Datatype not in the W3C-recommended set | "…"^^xsd:char |
ErrorKind.DATATYPE |
Datatype ≠ ontology rdfs:range |
"…"^^xsd:dateTime on a dbo:birthDate whose range is xsd:date |
ErrorKind.RANGE |
| Lexical form outside the Lexical Space | "11-11-1974"^^xsd:date (needs CCYY-MM-DD) |
ErrorKind.LEXICAL_FORM |
Value outside a constraining facet (min/max/length) |
"1800-01-01"^^xsd:date when the ontology requires ≥ 1900-01-01 |
ErrorKind.FACET |
| Typed literal on an ObjectProperty | ?m dbo:director "…"^^xsd:string |
ErrorKind.STRUCTURAL |
| Functional / inverse-functional / symmetric / asymmetric axiom breach (requires SHACL shapes) | via a supplied SHACL shapes graph | ErrorKind.OBJECT_AXIOM |
FILTER expressions with <, >, <=, >=, = are also facet-checked. On
strict comparisons the boundary constant is adjusted by +/-1 before the
membership test (> moves to c+1, < to c-1) so the value actually
subject to the filter, not the boundary itself, is what gets checked.
Extensibility
Every phase is an ABC - swap any implementation without touching the façade:
from sparql_validator import SPARQLValidator
from sparql_validator.interfaces import IQueryDecomposer
from sparql_validator.phases import (
DefaultLiteralValidator, RdflibTripleGenerator, PySHACLGraphValidator,
)
class MyRdflibParserDecomposer(IQueryDecomposer):
def decompose(self, query): ...
validator = SPARQLValidator(
ontology=my_onto, shapes=my_shapes,
decomposer=MyRdflibParserDecomposer(),
literal_validator=DefaultLiteralValidator(),
triple_generator=RdflibTripleGenerator(),
graph_validator=PySHACLGraphValidator(),
)
Development
uv sync --group dev
uv run ruff check
uv run mypy src
uv run pytest -q
References
The initial implementation of the SQV algorithm is inspired by:
J. Collio, A. Aguilera and I. Dongo, "Efficient Method for Validating SPARQL Queries Using Semantic Web Ontologies," 2025 LI Latin American Computer Conference (CLEI), Valparaíso, Chile, 2025, pp. 1-10, doi: 10.1109/CLEI67442.2025.11420331
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 sparql_validator-0.1.0.tar.gz.
File metadata
- Download URL: sparql_validator-0.1.0.tar.gz
- Upload date:
- Size: 66.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5e1d4fd8435b08a68aca186e2e08ca3b9cc4e2fc31934985b39e9748b783c4d
|
|
| MD5 |
07c045a2e015da1279b567d6a84cdcfd
|
|
| BLAKE2b-256 |
b2c9ed93a651b99006947d5ed69039f1a833cef26c0e0d6c15bb90dbfa6dfb19
|
Provenance
The following attestation bundles were made for sparql_validator-0.1.0.tar.gz:
Publisher:
publish-to-pypi.yml on dacamposol/sparql-validator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sparql_validator-0.1.0.tar.gz -
Subject digest:
d5e1d4fd8435b08a68aca186e2e08ca3b9cc4e2fc31934985b39e9748b783c4d - Sigstore transparency entry: 2128181193
- Sigstore integration time:
-
Permalink:
dacamposol/sparql-validator@889b2089b88ac69fff211e3491e1e51cf21f50cc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dacamposol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@889b2089b88ac69fff211e3491e1e51cf21f50cc -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file sparql_validator-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sparql_validator-0.1.0-py3-none-any.whl
- Upload date:
- Size: 35.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f9c3eb35e25bae3d15e7f929d4c3ae46763afe0769a682cef20a10ef595cfcfa
|
|
| MD5 |
d8dadf848187adc5e257e32a2faefa6f
|
|
| BLAKE2b-256 |
47a4bc3f507078c1dfed7853f993b6b1f526fd57ca2990e8e3d05c397c676104
|
Provenance
The following attestation bundles were made for sparql_validator-0.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on dacamposol/sparql-validator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sparql_validator-0.1.0-py3-none-any.whl -
Subject digest:
f9c3eb35e25bae3d15e7f929d4c3ae46763afe0769a682cef20a10ef595cfcfa - Sigstore transparency entry: 2128181427
- Sigstore integration time:
-
Permalink:
dacamposol/sparql-validator@889b2089b88ac69fff211e3491e1e51cf21f50cc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/dacamposol
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@889b2089b88ac69fff211e3491e1e51cf21f50cc -
Trigger Event:
workflow_dispatch
-
Statement type: