Fork of https://github.com/oxigraph/oxigraph.git for the purpose of NextGraph project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
oxigraph/python
Tpt 0a2566b100 Makes python tests stable with respect to quads ordering 4 years ago
..
src Converts oxigraph::Error into oxigraph::sparql::EvaluationError 4 years ago
tests Makes python tests stable with respect to quads ordering 4 years ago
Cargo.toml Adds basic Python bindings to Oxigraph 4 years ago
README.md Improves Python README 4 years ago
pyproject.toml Adds basic Python bindings to Oxigraph 4 years ago

README.md

Oxigraph for Python

actions status

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 memory
  • SledStore 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:

  1. data: the serialized RDF triples or quads.
  2. mime_type: the MIME type of the serialization. See below for the supported mime types.
  3. base_iri: the base IRI used to resolve the relative IRIs in the serialization.
  4. to_named_graph: for triple serialization formats, the name of the named graph the triple should be loaded to.

The available formats are:

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.