\page python Python Integration
KnowRob integrates with the Python language through the boost::python library.
The way it works is that the C++ classes are wrapped in Python classes
using the boost::python library.
The build process then creates a module file called knowrob.so that can be imported
in Python using e.g. import knowrob.
There are two main intended use cases:
- Python applications that internally manage a
KnowledgeBaseobject. - KnowRob plugins for
StorageandReasonerthat are written in Python: you can write a Python class that inherits fromStorageorReasonerand implement the virtual methods. For more details on how to write a Python plugin, see the README in the reasoner directory.
Currently, only the C++ classes which are needed for these use-cases are available in Python, i.e. the classes themselves and the types that appear in their public interfaces. Please further note that the integration is at an early stage, and some important features might still be missing. If you encounter one, please report it via the issue tracker.
To write a Python plugin for the reasoner, you need to create a Python class
that inherits from GoalDrivenReasoner or DataDrivenReasoner or one of its
subclasses, and implement the virtual methods.
An example of a Python reasoner plugin can be found in the tests directory.
A template for a reasoner that defined RDF relations is like this:
from knowrob import *
class MyReasonerType(RDFGoalReasoner):
def __init__(self):
super(DummyReasoner, self).__init__()
# The reasoner defines a new predicate that can be evaluated by the reasoner
self.defineRelation(IRIAtom("http://my.org/jealous"))
def initializeReasoner(self, config: PropertyTree) -> bool:
# Read reasoner specific settings from the configuration
return True
def evaluate(self, goal: RDFGoal) -> bool:
# The goal is a conjunction that contains a single RDF literal of the form jealous(s, o).
# There will not be any other literals in the goal as we have not enabled
# the use of complex formulas in the reasoner configuration (via enableFeature/1).
return TruePlease refer to the C API Documentation for more information on the available interfaces.
It can be loaded into KnowRob by adding a reasoner configuration to the settings file, e.g.:
{
"name": "my_reasoner",
"type": "MyReasonerType",
"module": "/path/to/my_reasoner.py",
"data-backend": "pl"
}This assumes that the Python module "my_reasoner.py" contains a class
"MyReasonerType" that inherits from GoalDrivenReasoner or DataDrivenReasoner.
It further connects to the Prolog storage backend "pl" which must be defined
in the settings file as well.
There are a couple of specifics that require special attention.
One of them is that there are problems when Python classes implement
multiple C++ interfaces. This could be useful to define a Reasoner which
is also a Storage, but it is not supported at the moment.
Another limitation is that when overwriting a virtual method in Python, it seems not possible to explicitly call the base class method. However, as a workaround for most cases a wrapper class can be defined on the C++ side that also calls the base class method.
Finally, the Python code is currently missing doc strings.
There is unfortunately no way to automatically generate them using
the boost::python library.
However, at a later point we could generate Python doc strings from the existing API
documentation using a custom target in the CMake build system.