Skip to main content

Vortex-RDF for Python

PyPI

Python bindings for Vortex-RDF, a columnar RDF store format built on Vortex. Stores are opened lazily from .vortex files and queried in place, without loading the dataset into memory. The bindings are read-only (mutations are in the roadmap): build .vortex files with serialize_rdf (file → file), then open and query them; in-memory builds are not yet supported.

A separate vortex-rdflib package builds an rdflib integration on these bindings; see its own documentation.

Install

pip install vortex-rdf

Quick start

from vortex_rdf import VortexRdfStore, serialize_rdf

serialize_rdf("data.nt", "data.vortex", layout="dictionary")   # RDF file -> .vortex file
store = VortexRdfStore("data.vortex")                            # lazy open; layout auto-detected
store.count_quads(p="<http://xmlns.com/foaf/0.1/name>")          # match count, no terms materialized
store.get_quads(p="<http://xmlns.com/foaf/0.1/name>")            # [(s, p, o, g), ...]

Reading quads

Every read takes a pattern as the keyword arguments s, p, o, g; an omitted position is a wildcard. Terms cross the boundary as N-Triples strings (<iri>, _:b0, "lit"@en, "3"^^<http://www.w3.org/2001/XMLSchema#integer>); the graph of a quad in the default graph is the empty string, which is also how a pattern selects it. A malformed term raises ValueError; a failing store operation raises VortexRdfError.

len(store)                                                   # number of quads
store.layout()                                               # "dictionary" | "default" | "typed-object"
store.indexes()                                              # e.g. ["secondary-by-reference"]
store.count_quads(p="<http://xmlns.com/foaf/0.1/name>")      # int
store.get_quads(p="<http://xmlns.com/foaf/0.1/name>")        # [(s, p, o, g), ...]
store.match_columns(p="<http://xmlns.com/foaf/0.1/name>")    # (subjects, predicates, objects, graphs)

get_quads returns whole quads; match_columns returns the same rows transposed into four parallel columns, for callers that work a position at a time. Both are served from the term-code columns whenever the store can (Dictionary layout, resident dictionary) and from the matched quads otherwise; results are identical. On the code path a term that repeats down a column is one shared Python string, so a caller converting terms into its own representation can rely on the cached string it is handed.

Term codes (low-level)

For Dictionary-layout stores, match_codes returns the matched rows as four zero-copy u32 term-code columns — memoryview(col).cast("I") views the Rust memory directly — decodable through a term_dict() handle:

cols = store.match_codes(p="<http://xmlns.com/foaf/0.1/name>")  # (s, p, o, g) or None
dictionary = store.term_dict()                                    # TermDict or None
subjects = memoryview(cols[0]).cast("I")
dictionary.decode(subjects[0])                       # N-Triples string for that code
dictionary.decode_many(cols[0])                      # bulk-decode a whole column
dictionary.encode("<http://xmlns.com/foaf/0.1/name>")  # code for a term, or None

decode_many decodes a batch in one GIL-released call. Buffer-protocol inputs — a column straight from match_codes, an array("I", ...), a uint32 NumPy array — are read in a single bulk copy with no per-element int conversion; any sequence of ints works too. encode is the inverse of decode. Both term_dict() and match_codes return None when the code path does not apply (a non-Dictionary layout, or a dictionary left file-backed by the residency budget).

Consumers can join, count, and de-duplicate entirely in code space and decode each distinct term once, never materializing a term string for a row they discard.

Build options

serialize_rdf(input_path, output_path, *, format=None, layout="dictionary", indexes=[])

Every option after the two paths is keyword-only. format is an RDF format name ("ntriples", "nquads", "turtle", "trig", "n3", "rdfxml", "jsonld", or the short aliases nt, nq, ttl, rdf, xml), detected from the input file extension when omitted. Opening auto-detects the layout and indexes — VortexRdfStore takes no layout argument; store.layout() and store.indexes() report the same names.

layout — how terms are encoded into columns. "dictionary" is the default in every vortex-rdf frontend (Python, JS and the CLI):

Value Notes
"dictionary" (default) Terms replaced by codes into a sorted term dictionary. Most compact and fastest to query; backs match_codes/term_dict
"default" All four terms as N-Triples strings
"typed-object" Object split into kind/value/datatype/language columns

indexes — secondary access paths, each costing extra space:

Value Notes
"secondary-by-reference" Sorted predicate/object columns plus row-id back-references, so predicate-only and object-only patterns use a binary search instead of a full scan
"secondary-by-copy" Two complete extra copies of the quad columns — one sorted by (p, o, s, g), one by (o, s, p, g) — giving predicate- and object-bound patterns (including predicate+object prefix lookups) the same sorted access path subjects have

Bytes & files

The default open is lazy and file-backed. VortexRdfStore(path, in_memory=True) loads the store into memory once, so each subsequent match skips the per-call file-scan pipeline.

For Dictionary-layout files the term dictionary is lifted into memory when its compressed size in the file fits the residency budget — 512 MiB by default, overridable process-wide with VORTEX_RDF_DICT_MAX_RESIDENT_BYTES. VortexRdfStore(path, max_resident_bytes=n) sets the budget for that open (the environment variable is ignored for it). A dictionary left file-backed is point-read through its chunk leaves; term_dict() and match_codes then return None and the string reads fall back to the matched quads.

Stores also round-trip through bytes: store.to_bytes() serializes to the native container (the same exchange format as the .vortex file, the CLI and the JS bindings), and VortexRdfStore.from_bytes(data) opens such a buffer — bytes or bytearray — as a fully in-memory store.

Development

Managed with uv; maturin runs under the hood as the build backend:

cd python
uv sync                      # creates .venv, builds + installs the extension
uv run pytest tests          # run the test suite
uv run maturin develop --uv  # fast rebuild while iterating on Rust code

Rust source changes are picked up by uv sync automatically (see [tool.uv] cache-keys in pyproject.toml). Without uv: python -m venv .venv && pip install maturin pytest && maturin develop && pytest tests.

Building from source (the sdist or a development build) additionally requires libclang: a transitive build dependency of the Vortex file engine (custom-labels, via vortex-io) generates C bindings with bindgen at compile time. It is preinstalled on most dev setups (Xcode, LLVM on Windows); on Linux install e.g. clang-devel (dnf) or libclang-dev (apt). Installing a published wheel needs none of this.

Benchmarks

bench/run.py measures these bindings against pyoxigraph, pycottas, rdflib and lightrdf on a file → store → query workload and writes bench/results.json for the dashboard's Python tab; bench/test_codspeed.py is the instrumented suite CodSpeed runs.

python3 python/bench/run.py                 # full run
BENCH_DIM=32 python3 python/bench/run.py    # quick pilot
uv run pytest bench/test_codspeed.py --codspeed

Harness design (per-library virtualenvs, dataset parity with js/bench/datasets.ts, unsupported cells where a library lacks the operation, matched-row counts cross-checked and any disagreement recorded in config.countWarnings) is documented in bench/run.py, bench/worker.py and bench/adapters.py. Configuration variables:

Var Default Meaning
BENCH_SIZE 1,048,576 rows (value shared with the Rust and JS suites)
BENCH_DIM unset optional cube shorthand, rows; ignored if BENCH_SIZE is set
BENCH_GRAPHS_QUADS 8 named graphs the comparative bench asks for
MUT_BATCH 10000 quads per add/delete batch
BENCH_PYTHON 3.13 Python version the per-library virtualenvs are provisioned with
BENCH_SUBJ_RATIO / BENCH_OBJ_RATIO 0.1 / 0.5 distinct subjects / objects per row
BENCH_PREDICATES 32 distinct predicates
BENCH_GRAPHS 1 distinct named graphs in the generator; 1 means default graph only
BENCH_LITERAL_FRAC 0.4 fraction of objects that are literals
BENCH_SLOW_PHASE_MS 30000 a phase slower than this runs once, without warmup
PY_BENCH_QUERY_ITERS / PY_BENCH_QUERY_WARMUP 10 / 5 measured / warmup iterations per query
PY_BENCH_HEAVY_ITERS / PY_BENCH_FULL_SCAN_ITERS 3 / 3 iterations for the heavy and full-scan phases
CODSPEED_BENCH_DIM / CODSPEED_BENCH_DIM_QUADS 32 / 13 CodSpeed suite: triples / D⁴ quads

License

MIT

Download files

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

Source Distribution

vortex_rdf-0.10.0.tar.gz (416.2 kB view details)

Uploaded Source

Built Distributions

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

vortex_rdf-0.10.0-cp311-abi3-win_amd64.whl (13.2 MB view details)

Uploaded CPython 3.11+Windows x86-64

vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_x86_64.whl (12.7 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ x86-64

vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_aarch64.whl (11.4 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ARM64

vortex_rdf-0.10.0-cp311-abi3-macosx_11_0_arm64.whl (12.0 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

vortex_rdf-0.10.0-cp311-abi3-macosx_10_12_x86_64.whl (12.5 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file vortex_rdf-0.10.0.tar.gz.

File metadata

  • Download URL: vortex_rdf-0.10.0.tar.gz
  • Upload date:
  • Size: 416.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vortex_rdf-0.10.0.tar.gz
Algorithm Hash digest
SHA256 da164b03f2a2f4bb4bfe12d0b2f663cda4be7e968a32917cc6d6e91d9e88ed6e
MD5 5dd1a0244f603969039e8f4dbbffacee
BLAKE2b-256 d5a9530edb05b324963ce48d2f3c3c4ad20577248aecaace6078a231ee34f071

See more details on using hashes here.

Provenance

The following attestation bundles were made for vortex_rdf-0.10.0.tar.gz:

Publisher: release.yml on vortex-rdf/vortex-rdf

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

File details

Details for the file vortex_rdf-0.10.0-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: vortex_rdf-0.10.0-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 13.2 MB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vortex_rdf-0.10.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 b9b10816bc3ef41c9eebcb23c5f8732d86b0fc3c1daceb6377e05b8e5c0dd9b6
MD5 1e444e73a953eee1c8f2da2e339cef80
BLAKE2b-256 045659ee561d496e934c2200c4ba0d04d77efb6aaaed9f8f7f787eb47edf2847

See more details on using hashes here.

Provenance

The following attestation bundles were made for vortex_rdf-0.10.0-cp311-abi3-win_amd64.whl:

Publisher: release.yml on vortex-rdf/vortex-rdf

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

File details

Details for the file vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 676da23a0829fbf76bb773b3473ea3ac7ad8019e76cd498bcc138e099b215256
MD5 8d3d14187eacd229477789010a9026a5
BLAKE2b-256 f0b8c45fc67d3ecee87a3eea2b7d9fb384d3c09c9e8dc0ac1e6b9f035aaaff79

See more details on using hashes here.

Provenance

The following attestation bundles were made for vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on vortex-rdf/vortex-rdf

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

File details

Details for the file vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 97d5d5393c2eca6d06ce0f3e805127b4cc04a93dfccdcdd5a70beef688d70f02
MD5 7121b6f24ac85d829d45ce8599332e0e
BLAKE2b-256 dada4f063af3704ca51fd43e42f2df748b8adaed1da5c15093f7f7cd26dd0ade

See more details on using hashes here.

Provenance

The following attestation bundles were made for vortex_rdf-0.10.0-cp311-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on vortex-rdf/vortex-rdf

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

File details

Details for the file vortex_rdf-0.10.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for vortex_rdf-0.10.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a379134ba63f17ede3d2cc475191b0119dbab9cdd43bc4848f79d5919fee9391
MD5 fb65c9d0b38a265f083801ae533d874c
BLAKE2b-256 25e99ddc9a04cf577afb7e78b6ce62376f5e83130b226c0a36eb0317d90ccb82

See more details on using hashes here.

Provenance

The following attestation bundles were made for vortex_rdf-0.10.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on vortex-rdf/vortex-rdf

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

File details

Details for the file vortex_rdf-0.10.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for vortex_rdf-0.10.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 dafe84c46a4f3385ab40090ce7451731329923416e5aa2ccca8dd9ef6bf41184
MD5 4c09bba1df49ddb5d58f764a8e6fca16
BLAKE2b-256 8d290a89b1216427bc39e77f663309924ce4770f0040829eb78f3a101cdcf895

See more details on using hashes here.

Provenance

The following attestation bundles were made for vortex_rdf-0.10.0-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on vortex-rdf/vortex-rdf

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

Release history Release notifications | RSS feed

This release

0.10.0 This release

6 files

0.5.0

6 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page