Skip to main content

PurRDF for Python

PyPI License: MIT OR Apache-2.0 Python versions

PurRDF is a from-scratch, dependency-light RDF 1.2 engine — parsers and serializers, SPARQL, SHACL, ShEx, RDFC-1.0 canonicalization, and the GTS graph-transport container — written in Rust and carried verbatim into Python, JavaScript, and C. The purrdf package is the Python surface of that one engine: the same byte-identical semantics in every language, including triple terms, reifiers, and base-direction literals that most incumbent libraries do not carry.

Install

pip install purrdf

Requires Python 3.13+. Wheels bundle the native extension; no Rust toolchain needed.

Parse RDF

import purrdf

quads = purrdf.parse(
    '<https://example.org/alice> <http://xmlns.com/foaf/0.1/name> "Alice" .',
    purrdf.RdfFormat.TURTLE,
)

purrdf.parse accepts Turtle, TriG, N-Triples, N-Quads, TriX, and HexTuples (purrdf.RdfFormat); JSON-LD and RDF/XML travel through the dedicated purrdf.from_json_ld / purrdf.to_json_ld and purrdf.from_rdf_xml / purrdf.to_rdf_xml converters. All codecs are first-party with byte-deterministic output.

Project graph, tabular, and research-object carriers

purrdf.project and purrdf.lift are thin calls into the same Rust projection engine used by every other surface. Configuration is mandatory, strict JSON: PurRDF supplies no vocabulary, identity IRI, or resource-limit default.

import json
import purrdf

config = json.dumps({
    "profile": "lpg-csv",
    "config": {
        "rdf_type": "https://example.org/type",
        "limits": {
            "max_artifacts": 16,
            "max_artifact_bytes": 1_000_000,
            "max_total_bytes": 4_000_000,
            "max_archive_bytes": 5_000_000,
            "max_term_depth": 16,
        },
        "max_records": 1_000,
    },
})
package = purrdf.project(
    "@prefix ex: <https://example.org/> . ex:alice ex:knows ex:bob .",
    format=purrdf.RdfFormat.TURTLE,
    profile="lpg-csv",
    config=config,
)
lifted = purrdf.lift(package.archive, profile="lpg-csv", config=config)
assert lifted.dataset.quad_count() == 1
print([(loss.code, loss.location) for loss in package.losses])

Project profiles are lpg-csv, neo4j-csv, open-cypher, graphml, csvw-exact, obo-graphs, skos, croissant-1.1, ro-crate-1.3, datacite-4.6, dcat-3, and frictionless-data-package-1. Only OBO Graphs and SKOS are deliberately write-only, ledgered views. Returned archives are canonical deterministic USTAR bytes and every result carries its always-computed structured loss records. Research-object contexts, vocabularies, identities, and profiles are all mandatory caller configuration. See the runnable projection_roundtrip.py file-producing example.

Validate with SHACL

The SHACL engine lives at purrdf.shapes (mirroring the Rust crate; purrdf.shacl is a back-compat alias):

from purrdf import shapes

report = shapes.validate(shapes_ttl=my_shapes, data_nt=my_data)
print(report["conforms"])

Complete SHACL Core, SHACL-SPARQL constraints/targets, and SHACL-AF sh:rule entailment via shapes.entail(...). Reusable parsed shapes are available as shapes.Shapes(shapes_ttl).validate_nt(data_nt).

Validate with ShEx

from purrdf import shex

results = shex.validate(
    my_schema_shexc,
    my_data_ttl,
    [("https://example.org/alice", "https://example.org/PersonShape")],
)
print(all(entry["conformant"] for entry in results))

The ShEx 2.1 validator passes 1,051/1,051 attempted validation tests of the official shexTest suite (see the repo's docs/CONFORMANCE.md).

rdflib compatibility layer

The package ships an rdflib-shaped API over the native engine:

from purrdf.compat.rdflib import Graph, URIRef

g = Graph()
g.parse(data=my_ntriples, format="nt")
print(len(g), g.serialize(format="turtle"))

For a literal, zero-change import rdflib, install the opt-in extra:

pip install purrdf[rdflib]

This pulls in the separate purrdf-rdflib distribution, whose top-level rdflib package re-exports the compat surface, so existing third-party code doing import rdflib / from rdflib.namespace import RDF transparently runs on purrdf. Caveat: that shadow claims the rdflib import name and must never be installed alongside the genuine rdflib — the two cannot co-inhabit one environment. It is a separate distribution (never bundled into the main purrdf wheel) precisely so environments that need the real rdflib simply omit it.

GTS graph transport and relational exports

GTS is PurRDF's single-file, content-addressed, append-only container for RDF 1.2 graphs. Build one from quads and export it straight to relational stores:

import purrdf

gts_bytes = purrdf.gts_from_quads(my_nquads_bytes, format=purrdf.RdfFormat.N_QUADS)

purrdf.gts_to_sqlite(gts_bytes, "graph.db")
purrdf.gts_to_duckdb(gts_bytes, "graph.duckdb")
files = purrdf.gts_to_parquet(gts_bytes, "out/")

The same entry points are grouped under purrdf.gts for discoverability.

Learn more

Licensed under MIT OR Apache-2.0, at your option.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

purrdf-0.7.0.tar.gz (2.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

purrdf-0.7.0-cp313-abi3-manylinux_2_34_x86_64.whl (5.4 MB view details)

Uploaded CPython 3.13+manylinux: glibc 2.34+ x86-64

File details

Details for the file purrdf-0.7.0.tar.gz.

File metadata

  • Download URL: purrdf-0.7.0.tar.gz
  • Upload date:
  • Size: 2.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for purrdf-0.7.0.tar.gz
Algorithm Hash digest
SHA256 b0b4e31f980ef00438b11473a117b567a27f6e5fbad8c644daa16c60793f8a8a
MD5 dd4bce5eadcb2bea574490acb771420d
BLAKE2b-256 cd43e878409cbb8e195b7e8508d2a712460c538ed92bdb535cccedbc576858ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for purrdf-0.7.0.tar.gz:

Publisher: release-pypi.yaml on Blackcat-Informatics/purrdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file purrdf-0.7.0-cp313-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for purrdf-0.7.0-cp313-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 f041008d13938bfc67c8349b95a38f77a845168dbfeba4fb7e2097e06c266725
MD5 cfecec8f1749ae3d8d3c35ba65be8fdc
BLAKE2b-256 406230e5241ad60d67fa8fb05ad5dbf1e42a1c4feb18bc4871ee44f8acffc4ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for purrdf-0.7.0-cp313-abi3-manylinux_2_34_x86_64.whl:

Publisher: release-pypi.yaml on Blackcat-Informatics/purrdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page