SPARQL Burger
SPARQL Burger is a Python SPARQL query builder that automates the generation of SPARQL graph patterns, SPARQL Select and SPARQL Update queries. Just like stacking onions, tomatos and cheese to assemble the right burger, SPARQL Burger offers the necessary ingredients for the assembly of meaningful SPARQL queries in an OOP manner.

Getting Started
SPARQL Burger is a minimal module for Python (2.x. and 3.x).
Prerequisites
None
Installation
- Save the
SPARQLBurger
folder to your project's directory.
pip install SPARQL-Burger
Usage examples
1. Create a SPARQL graph pattern and add some triples
In this example we generate a minimal SPARQL graph pattern. A graph pattern, delimited with { }
, is a building block for SPARQL queries and more than one can be nested and/or united to form a more complex graph pattern.
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
pattern = SPARQLGraphPattern()
pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="ex:hasName", object="?name")
]
)
print(pattern.get_text())
The printout is:
{
?person rdf:type ex:Person .
?person ex:hasName ?name .
}
2. Create an OPTIONAL pattern and nest it to the main pattern
Here, the main graph pattern contains another graph pattern that is declared as OPTIONAL. In general, graph patterns can contain as many nesting levels as necessary. Nesting a pattern to itself, though, would result to an error.
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
main_pattern = SPARQLGraphPattern()
main_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="ex:hasName", object="?name")
]
)
optional_pattern = SPARQLGraphPattern(optional=True)
optional_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="ex:hasAge", object="?age")
]
)
main_pattern.add_nested_graph_pattern(optional_pattern)
print(pattern.get_text())
The printout is:
{
?person rdf:type ex:Person .
?person ex:hasName ?name .
OPTIONAL {
?person ex:hasAge ?age .
}
}
3. Create a UNION of graph patterns
In this example we will declare a main graph pattern that contains two other graph patterns associated with UNION.
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
main_pattern = SPARQLGraphPattern()
first_pattern = SPARQLGraphPattern()
first_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="ex:hasName", object="?name")
]
)
second_pattern = SPARQLGraphPattern(union=True)
second_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:User"),
Triple(subject="?person", predicate="ex:hasNickname", object="?name")
]
)
main_pattern.add_nested_graph_pattern(graph_pattern=first_pattern)
main_pattern.add_nested_graph_pattern(graph_pattern=second_pattern)
print(main_pattern.get_text())
The printout is:
{
{
?person rdf:type ex:Person .
?person ex:hasName ?name .
}
UNION
{
?person rdf:type ex:User .
?person ex:hasNickname ?name .
}
}
4. Adding FILTER, BIND and IF definitions
So far we have created simple and nested graph patterns. Now let's see how to add filters, bindings and if clauses.
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
pattern = SPARQLGraphPattern()
pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="ex:hasAge", object="?age")
]
)
pattern.add_filter(
filter= Filter(
expression="?age < 65"
)
)
pattern.add_binding(
binding=Binding(
value="?age",
variable="?years_alive"
)
)
pattern.add_binding(
binding=Binding(
value=IfClause(
condition="?age >= 18",
true_value="'adult'",
false_value="'minor'"
),
variable="?status"
)
)
print(pattern.get_text())
The printout is:
{
?person rdf:type ex:Person .
?person ex:hasAge ?age .
BIND (?age AS ?years_alive)
BIND (IF (?age >= 18, 'adult', 'minor') AS ?status)
FILTER (?age < 65)
}
In the first BIND we have only provided a value and a variable as string, but this is not always the case. In the second BIND we nested an IF clause. Therefore, the Binding.value
also accepts objects of classes like IfClause
. In a similar way, the arguments of IfClause
can also be other objects of type IfClause
and Bound
in a nested format, as shown below.
from SPARQLBurger.SPARQLQueryBuilder import *
pattern = SPARQLGraphPattern()
pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
]
)
optional_pattern = SPARQLGraphPattern(optional=True)
optional_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="ex:hasAddress", object="?address")
]
)
pattern.add_binding(
binding=Binding(
value=IfClause(
condition=Bound(
variable="?address"
),
true_value="?address",
false_value="'Unknown'"
),
variable="?address"
)
)
print(pattern.get_text())
The printout is:
{
?person rdf:type ex:Person .
BIND (IF (BOUND (?address), ?address, 'Unknown') AS ?address)
}
5. Create a SPARQL Select query
Now that we have mastered the definition of graph patterns, let's create a simple Select query.
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
select_query = SPARQLSelectQuery(distinct=True, limit=100)
select_query.add_prefix(
prefix=Prefix(prefix="ex", namespace="http://www.example.com#")
)
select_query.add_variables(variables=["?person", "?age"])
where_pattern = SPARQLGraphPattern()
where_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="ex:hasAge", object="?age"),
Triple(subject="?person", predicate="ex:address", object="?address"),
]
)
select_query.set_where_pattern(graph_pattern=where_pattern)
select_query.add_group_by(
group=GroupBy(
variables=["?age"]
)
)
print(select_query.get_text())
The printout is:
PREFIX ex: <http://www.example.com#>
SELECT DISTINCT ?person ?age
WHERE {
?person rdf:type ex:Person .
?person ex:hasAge ?age .
?person ex:address ?address .
}
GROUP BY ?age
LIMIT 100
6. Create a SPARQL Update query
Quite similarly we can exploit graph patterns to create a SPARQL Update query (in the DELETE/INSERT form).
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
update_query = SPARQLUpdateQuery()
update_query.add_prefix(
prefix=Prefix(prefix="ex", namespace="http://www.example.com#")
)
delete_pattern = SPARQLGraphPattern()
delete_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="ex:hasAge", object="?age")
]
)
insert_pattern = SPARQLGraphPattern()
insert_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="ex:hasAge", object="32")
]
)
where_pattern = SPARQLGraphPattern()
where_pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="ex:hasAge", object="?age")
]
)
update_query.set_delete_pattern(graph_pattern=delete_pattern)
update_query.set_insert_pattern(graph_pattern=insert_pattern)
update_query.set_where_pattern(graph_pattern=where_pattern)
print(update_query.get_text())
The printout is:
PREFIX ex: <http://www.example.com#>
DELETE {
?person ex:hasAge ?age .
}
INSERT {
?person ex:hasAge 32 .
}
WHERE {
?person rdf:type ex:Person .
?person ex:hasAge ?age .
}
7. Reference multiple URIs with VALUES
By defining a VALUES, it is possible to reference multiple URIs by a single variable name
Show example
from SPARQLBurger.SPARQLQueryBuilder import *
pattern = SPARQLGraphPattern()
uris = ["https://www.wikidata.org/entity/Q42",
"https://www.wikidata.org/entity/Q46248"]
pattern.add_value(value=Values(values=uris, name="?friend"))
pattern.add_triples(
triples=[
Triple(subject="?person", predicate="rdf:type", object="ex:Person"),
Triple(subject="?person", predicate="foaf:knows", object="?friend")
]
)
print(pattern.get_text())
The printout is:
{
VALUES ?friend {<https://www.wikidata.org/entity/Q42> <https://www.wikidata.org/entity/Q46248>}
?person rdf:type ex:Person .
?person foaf:knows ?friend .
}
Tests
To run the tests, install pytest
via
pip install pytest
Subsequently run
pytest
Documentation
The official webpage - The Docs
Authors