tools4rdf#
tools4RDF is a Python toolkit designed to simplify working with RDF data, ontologies, and knowledge graphs. It provides user-friendly utilities for creating, manipulating, querying, and visualizing RDF data, making it easier to integrate semantic web technologies into research and applications, particularly for domain scientists and developers without deep RDF expertise.
It is built on top of rdflib, and a primary function is the automated creation of SPARQL queries through an autocompleted programmatic interface.
Explore the examples below to get started with tools4rdf and see how it can accelerate your semantic data workflows!
A small example#
from tools4rdf import OntologyNetwork
Read in the FOAF ontology
onto = OntologyNetwork('http://purl.org/spar/foaf')
Explore terms, autocompletion works!
onto.terms.foaf.Person
foaf:Person
onto.terms.foaf.Person.uri, onto.terms.foaf.Person.description
('http://xmlns.com/foaf/0.1/Person',
rdflib.term.Literal('A person.', datatype=rdflib.term.URIRef('http://www.w3.org/2001/XMLSchema#string')))
Another term
onto.terms.foaf.name
foaf:name
Find domain and range of the term
onto.terms.foaf.name.domain, onto.terms.foaf.name.range
(['foaf:Agent',
'foaf:Project',
'foaf:Document',
'foaf:Person',
'foaf:Group',
'foaf:Organization',
'foaf:Image',
'foaf:PersonalProfileDocument'],
[])
Build SPARQL queries automatically, and execute them on endpoints
df = onto.query(
'https://dbpedia.org/sparql',
onto.terms.foaf.Person,
onto.terms.foaf.name,
limit=10,
)
df
---------------------------------------------------------------------------
KeyboardInterrupt Traceback (most recent call last)
Cell In[7], line 1
----> 1 df = onto.query(
2 'https://dbpedia.org/sparql',
3 onto.terms.foaf.Person,
4 onto.terms.foaf.name,
5 limit=10,
6 )
7 df
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/checkouts/stable/tools4rdf/network/network.py:963, in Network.query(self, kg, source, destinations, return_df, num_paths, limit)
961 res = []
962 for query_string in query_strings:
--> 963 r = self._query(kg, query_string, return_df=return_df)
964 if r is not None:
965 res.append(r)
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/checkouts/stable/tools4rdf/network/network.py:1009, in Network._query(self, kg, query_string, return_df)
1007 break
1008 labels = [x[1:] for x in line.split()[2:]]
-> 1009 return pd.DataFrame(res, columns=labels)
1011 return res
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/site-packages/pandas/core/frame.py:829, in DataFrame.__init__(self, data, index, columns, dtype, copy)
827 data = np.asarray(data)
828 else:
--> 829 data = list(data)
830 if len(data) > 0:
831 if is_dataclass(data[0]):
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/site-packages/rdflib/query.py:346, in Result.__len__(self)
344 return 1
345 elif self.type == "SELECT":
--> 346 return len(self.bindings)
347 else:
348 # type error: Argument 1 to "len" has incompatible type "Optional[Graph]"; expected "Sized"
349 return len(self.graph)
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/site-packages/rdflib/query.py:232, in Result.bindings(self)
228 """
229 a list of variable bindings as dicts
230 """
231 if self._genbindings:
--> 232 self._bindings += list(self._genbindings)
233 self._genbindings = None
235 return self._bindings
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py:565, in evalDistinct(ctx, part)
562 res = evalPart(ctx, part.p)
564 done = set()
--> 565 for x in res:
566 if x not in done:
567 yield x
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py:573, in <genexpr>(.0)
571 def evalProject(ctx: QueryContext, project: CompValue):
572 res = evalPart(ctx, project.p)
--> 573 return (row.project(project.PV) for row in res)
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/site-packages/rdflib/plugins/sparql/evaluate.py:378, in evalServiceQuery(ctx, part)
376 json_dict = orjson.loads(response.read())
377 else:
--> 378 json_dict = json.loads(response.read())
379 variables = res["vars_"] = json_dict["head"]["vars"]
380 # or just return the bindings?
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/http/client.py:489, in HTTPResponse.read(self, amt)
487 else:
488 try:
--> 489 s = self._safe_read(self.length)
490 except IncompleteRead:
491 self._close_conn()
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/http/client.py:638, in HTTPResponse._safe_read(self, amt)
631 def _safe_read(self, amt):
632 """Read the number of bytes requested.
633
634 This function should be used when <amt> bytes "should" be present for
635 reading. If the bytes are truly not available (due to EOF), then the
636 IncompleteRead exception can be used to detect the problem.
637 """
--> 638 data = self.fp.read(amt)
639 if len(data) < amt:
640 raise IncompleteRead(data, amt-len(data))
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/socket.py:718, in SocketIO.readinto(self, b)
716 while True:
717 try:
--> 718 return self._sock.recv_into(b)
719 except timeout:
720 self._timeout_occurred = True
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/ssl.py:1314, in SSLSocket.recv_into(self, buffer, nbytes, flags)
1310 if flags != 0:
1311 raise ValueError(
1312 "non-zero flags not allowed in calls to recv_into() on %s" %
1313 self.__class__)
-> 1314 return self.read(nbytes, buffer)
1315 else:
1316 return super().recv_into(buffer, nbytes, flags)
File ~/checkouts/readthedocs.org/user_builds/tools4rdf/conda/stable/lib/python3.11/ssl.py:1166, in SSLSocket.read(self, len, buffer)
1164 try:
1165 if buffer is not None:
-> 1166 return self._sslobj.read(len, buffer)
1167 else:
1168 return self._sslobj.read(len)
KeyboardInterrupt:
We can take a look at the SPARQL query that was executed:
q = onto.create_query(
onto.terms.foaf.Person,
onto.terms.foaf.name,
limit=10,
)
print(q)
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?Person ?namevalue
WHERE {
?Person foaf:name ?namevalue .
?Person rdf:type foaf:Person .
}
LIMIT 10
Other features include:
Automated SPARQL query of both local knowledge graphs and remote endpoints
Read and parse ontologies
Combine ontologies programatically and connect them
For more examples, please check here
Supported SPARQL keywords#
The queries automatically generated by tools4RDF incorporates the following SPARQL features:
PREFIXdeclarations: Automatically generated from the ontologies and namespaces in useSELECT DISTINCT: All queries use SELECT DISTINCT to retrieve unique resultsWHEREclause: Triple patterns are constructed based on the paths between source and destination termsLIMIT: The number of results can be restricted using thelimitparameterType assertions: Automatic generation of
rdf:typestatements for classesSubclass support: When subclasses are included,
UNIONclauses are generated to match any subclassComparison operators:
<,>,<=,>=,==,!=Logical operators:
&&,||for combining conditionsXSD datatype support: Filters are generated with appropriate XSD datatypes
Remote endpoints: Pass a SPARQL endpoint to the query