It’s Time to Add a New Semantic Tool to the Toolbox
In CWPK #17 of this Cooking with Python and KBpedia series, we discussed what we would need in an API to OWL. Our work so far with owlready2 continues to be positive, leading us to believe it will prove out in the end to be the right API solution for our objectives. But in that same CWPK #17 review we also indicated intrigue with the RDFLib option. We know there are some soft spots with owlready2 in areas such as format support for which RDFLib is strong. It is also the case that owlready2 lacks a SPARQL query option, another area in which RDFLib is strong. In fact, the data exchange methods we use in KBpedia rely directly on simple variants of RDF, especially in the N3 notation.
In recognition of these synergies, just has it had in embracing SQLite as a lightweight native quad store, owlready2 has put in place many direct relations to RDFLib, including in the data store. What I had feared would be a difficult challenge of integrating Python, Anaconda, Jupyter Notebook, owlready2, and RDFLib, turned out in fact to be a very smooth process. We introduce the newest RDFLib piece in today’s installment.
RDFLib is a Python library for interacting with the Resource Description Framework (RDF) language. It has been actively maintained over 15 years and is presently in version 5.x. RDFLib is particularly strong in the areas of RDF format support, SPARQL querying of endpoints (including local stores), and CSV file functionality. Our hope in incorporating RDFLib is to provide the most robust RDF/OWL platform available in Python.
Installing RDFLib
Enter this at the command prompt:
$ conda install rdflib
You will see the standard feedback to the terminal that the package is being downloaded and then integrated with the other packages in the system. The simple install command is possible because we had already installed conda-forge
as a channel within the Anaconda distribution system for Python as described in CWPK #9.
We are now ready to use RDFLib.
Basic Setup
OK, so we steer ourselves to the 24th installment in the CWPK directory and we fire up the system by invoking the command window from this directory. We enter $ jupyter notebook
at the prompt and then proceed through the Jupyter file manager to this cwpk-24-intro-rdflib.ipynb
file. We pick it, and then enter our standard set of opening commands to KBpedia:
kbpedia_reference_concepts.owl
= 'C:/1-PythonProjects/kbpedia/sandbox/kbpedia_reference_concepts.owl'
main # main = 'https://raw.githubusercontent.com/Cognonto/CWPK/master/sandbox/builds/ontologies/kbpedia_reference_concepts.owl'
= 'http://www.w3.org/2004/02/skos/core'
skos_file = 'C:/1-PythonProjects/kbpedia/sandbox/kko.owl'
kko_file # kko_file = 'https://raw.githubusercontent.com/Cognonto/CWPK/master/sandbox/builds/ontologies/kko.owl'
from owlready2 import *
= World()
world = world.get_ontology(main).load()
kb = kb.get_namespace('http://kbpedia.org/kko/rc/')
rc
= world.get_ontology(skos_file).load()
skos
kb.imported_ontologies.append(skos)
= world.get_ontology(kko_file).load()
kko kb.imported_ontologies.append(kko)
We could have done this first, but we need to import
the RDFLib package into our active environment:
import rdflib
Depending on our use of RDFLib going forward, we could restrict this import to only certain modules in the package, but we load it all in this case.
Now, here is where the neat trick used by owlready2 in working with RDFLib comes into play. RDFLib also uses (in the standard case) SQLite as its backend. So, we point to the namespace graph
(could be any name) that RDFLib expects, but we assign it to the namespace (in this case, world
) already recognized by owlready2:
= world.as_rdflib_graph() graph
We now may manipulate the knowledge graph as we would in a standard way using (in this case) the namespace world
for owlready2 and access all of the additional functionality available via RDFLib using the (in this case) the graph
namespace. This is a great example of the Python ecosystem at work.
Further, because of even greater integration, there are some native commands in owlready2 that have been mapped to from RDFLib making the syntax and conventions in working with both libraries easier.
Initial SPARQL Examples
Of course, the reason we brought RDFLib into the picture at this point was to continue our exploration of querying the knowledge graph that began in our last installment, CWPK #23. We devote the next installment to a discussion of SPARQL queries in some depth, but let’s first test to see if our configuration is working properly.
In our first of two examples we present a fairly simple query in SPARQL format to our internal KBpedia reference concept store under the namespace graph
.
= list(graph.query_owlready("""
r PREFIX rc: <http://kbpedia.org/kko/rc/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?x ?label
WHERE
{
?x rdfs:subClassOf rc:Mammal.
?x skos:prefLabel ?label.
}
"""))
print(r)
[[rc.AbominableSnowman, 'abominable snowman'], [rc.Afroinsectiphilia, 'Afroinsectiphilia'], [rc.Eutheria, 'placental mammal'], [rc.Marsupial, 'pouched mammal'], [rc.Australosphenida, 'Australosphenida'], [rc.Bigfoot, 'Sasquatch'], [rc.Monotreme, 'monotreme'], [rc.Vampire, 'vampire'], [rc.Werewolf, 'werewolf']]
The above format looks more akin to a standard SPARQL query format. While it is a bit different, the example below is a more Python-like expression. Note as well that the three-quote convention tells Python to expect a multi-line code block:
= """
r PREFIX rc: <http://kbpedia.org/kko/rc/>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT DISTINCT ?x ?label
WHERE
{
?x rdfs:subClassOf rc:Mammal.
?x skos:prefLabel ?label.
}
"""
= list(graph.query_owlready(r))
results print(results)
[[rc.AbominableSnowman, 'abominable snowman'], [rc.Afroinsectiphilia, 'Afroinsectiphilia'], [rc.Eutheria, 'placental mammal'], [rc.Marsupial, 'pouched mammal'], [rc.Australosphenida, 'Australosphenida'], [rc.Bigfoot, 'Sasquatch'], [rc.Monotreme, 'monotreme'], [rc.Vampire, 'vampire'], [rc.Werewolf, 'werewolf']]
Additional Documentation
In the next installment we will provide SPARQL documentation. Here, however, are a couple of useful links to learn mora about RDFLib and its capabilibies:
*.ipynb
file. It may take a bit of time for the interactive option to load.