{"id":6815,"library":"pyshacl","title":"PySHACL: Python SHACL Validator","description":"PySHACL is a Python library that implements the W3C Shapes Constraint Language (SHACL) specification. It allows users to validate RDF data graphs against SHACL shapes, identify data quality issues, and generate detailed validation reports. Currently at version 0.31.0, the library maintains an active release cadence, with significant updates and fixes appearing every 1-3 months.","status":"active","version":"0.31.0","language":"en","source_language":"en","source_url":"https://github.com/RDFLib/pySHACL","tags":["rdf","shacl","validation","semantic-web","knowledge-graphs"],"install":[{"cmd":"pip install pyshacl","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency for RDF graph manipulation and parsing.","package":"rdflib","optional":false},{"reason":"Used for parsing SHACL syntax.","package":"lark","optional":false}],"imports":[{"symbol":"validate","correct":"from pyshacl import validate"}],"quickstart":{"code":"from pyshacl import validate\nfrom rdflib import Graph, Literal, URIRef\nfrom rdflib.namespace import SH, XSD\n\n# Define data graph and shapes graph in TTL format\ndata_graph_ttl = \"\"\"\n@prefix ex: <http://example.com/ns#> .\n@prefix sh: <http://www.w3.org/ns/shacl#> .\n\nex:John a ex:Person ;\n  ex:name \"John Doe\" .\n\nex:Jane a ex:Person . # This node will violate ex:PersonShape (missing ex:name)\n\"\"\"\n\nshapes_graph_ttl = \"\"\"\n@prefix ex: <http://example.com/ns#> .\n@prefix sh: <http://www.w3.org/ns/shacl#> .\n\nex:PersonShape a sh:NodeShape ;\n  sh:targetClass ex:Person ;\n  sh:property [\n    sh:path ex:name ;\n    sh:minCount 1 ;\n    sh:maxCount 1 ;\n    sh:datatype xsd:string ;\n  ] .\n\"\"\"\n\n# Load graphs using RDFLib\ndata_graph = Graph().parse(data=data_graph_ttl, format=\"ttl\")\nshapes_graph = Graph().parse(data=shapes_graph_ttl, format=\"ttl\")\n\n# Validate the data graph against the shapes graph\nconforms, results_graph, results_text = validate(\n    data_graph,\n    shacl_graph=shapes_graph,\n    inference='rdfs', # Perform RDFS inference before validation\n    serialize_report_graph=True # Return the report graph as an RDFLib Graph\n)\n\nprint(f\"Validation Conforms: {conforms}\")\nif not conforms:\n    print(\"\\nValidation Report:\")\n    print(results_text)\n    # for s, p, o in results_graph.triples((None, SH.resultMessage, None)):\n    #     print(f\" - {o}\")","lang":"python","description":"This example demonstrates how to validate a simple RDF data graph against a SHACL shapes graph using `pyshacl.validate`. It defines two in-memory graphs, one containing sample data and another defining a shape that requires every `ex:Person` to have exactly one `ex:name`. The validation identifies `ex:Jane` as non-conformant."},"warnings":[{"fix":"Upgrade Python to 3.8.1 or newer. For existing projects, pin PySHACL to `<0.25.0`.","message":"Support for Python 3.7 and earlier was dropped in PySHACL v0.25.0. Users on older Python versions must upgrade to Python 3.8.1+ or use a PySHACL version less than 0.25.0.","severity":"breaking","affected_versions":">=0.25.0"},{"fix":"Ensure your RDFLib installation is `rdflib>=6.3.2,<8.0.0` (or the latest compatible version) via `pip install --upgrade rdflib`.","message":"PySHACL v0.25.0 and later only support RDFLib versions 6.3.2 and higher. Older RDFLib versions (e.g., 6.2.0 or earlier) are no longer compatible.","severity":"breaking","affected_versions":">=0.25.0"},{"fix":"Upgrade to PySHACL v0.28.1 or newer to avoid unintended logging side effects. If unable to upgrade, consider configuring your logger *after* PySHACL initialization or using a named logger instead of the root logger.","message":"In PySHACL versions prior to v0.28.1, the library could aggressively overwrite the root Python logger, potentially removing other application-defined handlers. This was fixed in v0.28.1.","severity":"gotcha","affected_versions":"<0.28.1"},{"fix":"Review existing code that passes multiple data graphs. If independent validation per graph is desired, refactor to use `pyshacl.validate_each()` or loop through graphs calling `pyshacl.validate()` individually. Otherwise, be aware of the new combined dataset behavior.","message":"Starting with v0.31.0, the default behavior for validating multiple data graphs has changed. Providing multiple data graphs to the `validate` function will now combine them into a single `Dataset` for validation. For independent validation of each graph, use the new `validate_each()` entrypoint or the `--validate-each` CLI flag.","severity":"breaking","affected_versions":">=0.31.0"}],"env_vars":null,"last_verified":"2026-04-15T00:00:00.000Z","next_check":"2026-07-14T00:00:00.000Z","problems":[]}