7.0 KiB
Oxigraph for Python
This package provides a Python API on top of Oxigraph.
Oxigraph is a work in progress graph database written in Rust implementing the SPARQL standard.
It offers two stores with SPARQL 1.1 Query capabilities. One of the store is in-memory, and the other one is disk based.
The store is also able to load RDF serialized in Turtle, TriG, N-Triples, N-Quads and RDF XML.
Install
To install the development version of Oxigraph you need first to install the build tool Maturin.
This could be done using the usual pip install maturin
.
maturin build release
allows build a release Oxigraph Python wheel.
This wheel could be installed using pip install PATH
in the current Python environment where PATH
is the path to the built Oxigraph wheel.
Example
Insert the triple <http://example/> <http://schema.org/name> "example"
and print the name of <http://example/>
in SPARQL:
from oxigraph import *
store = MemoryStore()
ex = NamedNode('http://example/')
schemaName = NamedNode('http://schema.org/name')
store.add((ex, schemaName, Literal('example')))
for binding in store.query('SELECT ?name WHERE { <http://example/> <http://schema.org/name> ?name }'):
print(binding['name'].value)
API
Model
Oxigraph provides python classes for the basic RDF model elements.
NamedNode
An RDF IRI.
from oxigraph import NamedNode
assert NamedNode('http://example.com/foo').value == 'http://example.com/foo'
assert str(NamedNode('http://example.com/foo')) == '<http://example.com/foo>'
BlankNode
An RDF blank node.
from oxigraph import BlankNode
assert BlankNode('foo').value == 'foo'
assert str(BlankNode('foo')) == '_:foo'
Literal
An RDF literal.
from oxigraph import NamedNode, Literal
assert Literal('foo').value == 'foo'
assert str(Literal('foo')) == '"foo"'
assert Literal('foo', language='en').language == 'en'
assert str(Literal('foo', language='en')) == '"foo"@en'
assert Literal('11', datatype=NamedNode('http://www.w3.org/2001/XMLSchema#integer')).datatype == NamedNode('http://www.w3.org/2001/XMLSchema#integer')
assert str(Literal('11', datatype=NamedNode('http://www.w3.org/2001/XMLSchema#integer'))) == '"11"^^<http://www.w3.org/2001/XMLSchema#integer>'
DefaultGraph
The RDF default graph name.
from oxigraph import DefaultGraph
DefaultGraph()
Stores
Oxigraph provides two stores:
MemoryStore
that stores the RDF quads in memorySledStore
that stores the graph on disk using Sled.
Both stores provide a similar API. They encode an RDF dataset.
Constructor
MemoryStore
It could be constructed using:
from oxigraph import MemoryStore
store = MemoryStore()
SledStore
The following code creates a store using the directory foo/bar
for storage.
from oxigraph import SledStore
store = SledStore('foo/bar')
It is also possible to use a temporary directory that will be removed when the SledStore
Python object is dropped:
from oxigraph import SledStore
store = SledStore()
add
To add a quad in the store:
s = NamedNode('http://example.com/subject')
p = NamedNode('http://example.com/predicate')
o = NamedNode('http://example.com/object')
g = NamedNode('http://example.com/graph')
store.add((s, p, o, g))
If a triple is provided, it is added to the default graph i.e. store.add((s, p, o, g))
is the same as store.add((s, p, o, DefaultGraph()))
remove
To remove a quad from the store:
store.remove((s, p, o, g))
__contains__
Checks if a quad is in the store:
assert (s, p, o, g) in store
__len__
Returns the number of quads in the store:
assert len(store) == 1
__iter__
Iterates on all quads in the store:
assert list(iter(store)) == [(s, p, o, g)]
match
Returns all the quads matching a given pattern using an iterator.
Return all the quads with the subject s
:
assert list(store.match(s, None, None, None)) == [(s, p, o, g)]
Return all the quads in the default graph:
assert list(store.match(s, None, None, DefaultGraph())) == []
query
Executes a SPARQL 1.1 Query.
The ASK
queries return a boolean:
assert store.query('ASK { ?s ?s ?s }')
The SELECT
queries return an iterator of query solutions that could be indexed by variable name or position in the SELECT
clause:
for solution in store.query('SELECT ?s WHERE { ?s ?p ?o }'):
assert solution[0] == solution['s']
The CONSTRUCT
and DESCRIBE
queries return an iterator of triples:
for (s, p, o) in store.query('CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'):
print(s)
load
Loads serialized RDF triples or quad into the store. The method arguments are:
data
: the serialized RDF triples or quads.mime_type
: the MIME type of the serialization. See below for the supported mime types.base_iri
: the base IRI used to resolve the relative IRIs in the serialization.to_named_graph
: for triple serialization formats, the name of the named graph the triple should be loaded to.
The available formats are:
- Turtle:
text/turtle
- TriG:
application/trig
- N-Triples:
application/n-triples
- N-Quads:
application/n-quads
- RDF XML:
application/rdf+xml
Example of loading a Turtle file into the named graph <http://example.com/graph>
with the base IRI http://example.com
:
store.load('<http://example.com> <http://example.com> <> .', mime_type='text/turtle', base_iri="http://example.com", to_graph=NamedNode('http://example.com/graph'))
How to contribute
The Oxigraph bindings are written in Rust using PyO3.
They are build using Maturin.
Maturin could be installed using the usual pip install maturin
.
To install development version of Oxigraph just run maturin develop
.
The Python bindings tests are written in Python.
To run them use the usual python -m unittest
in the tests
directory.