How to write a plugin
What is a plugin?
A plugin is a software component that adds a specific feature to an existing computer program. When a program supports plug-ins, it enables customization (Wikipedia).
In the context of OAK, plugins allow you to add optional functionality to OAK.
An example of a plugin would be a code that uses a machine learning library such as Spacy or NLTK to provide an implementation of a text_annotator. We wouldn’t want to include this in the main library due to the additional dependencies required. But we might want to allow people to drop in this functionality, e.g.
runoak -i my_awesome_plugin: annotate "my text here"
An example plugin
oakx-robot is a plugin that implements the validator interface, providing access to OWL reasoners through robot.
You can use this programmatically by first installing it:
pip install oakx-robot
And then using the plugin’s selector, which is robot
:
runoak -i robot:tests/input/go-nucleus-unsat.owl validate
This can also be used programmatically
from oaklib.selector import get_resource_from_shorthand, discovered_plugins, get_adapter
from oakx_robot.robot_implementation import RobotImplementation, OWL_NOTHING
path = 'tests/input/go-nucleus-unsat.owl'
oi = get_adapter(f'robot:{path}')
if oi.is_coherent():
print('Congratulations! The ontology is coherent')
else:
print('Reasoner detected usatisfiable classes')
for c in oi.unsatisfiable_classes():
print(f'Unsatisfiable: {c}')
Creating a plugin
Discuss on the issue tracker
First make an issue on the OAK issue tracker - someone may be developing a plugin similar to yours! You will also want to propose the namespace/scheme you will use.
Create a new project
First create a new python project in the way you would normally do this.
We recommend using poetry, but you can adapt these to whichever system you like:
poetry new --src oakx-my-awesome-plugin
The project name should always start with oakx-
. Remember, poetry will make a python project that
uses underscores in the name
Then make sure OAK is added as a dependency:
poetry add oaklib
Implement one or more interfaces
Create an Implementation Class
Have this implement at least one interface
Implement
__post_init__()
, which initializes the implementation using a Resource object.
Example:
Implement a selector
OAK recognizes plugins by looking for entry points
in the oaklib.plugins
group. The name of each entry point should be the selector scheme you implement, and the object
reference of the entry point should be the corresponding implementation. The scheme should match the name used for your
project, and should be unique, concise, and descriptive. Don’t pollute the top level namespace!
The way you specify entry points will depend on the packaging tool your project uses. When using Poetry, your project
would include something like the following in pyproject.toml
:
[tool.poetry.plugins."oaklib.plugins"]
robot = "oakx_robot.robot_implementation:RobotImplementation"
If your project does not use Poetry, consult your build tool’s documentation for information on how to implement an entry point (e.g. using setuptools).
Write tests
Write tests as you would for any other project
See for example oakx-robot tests
Release to PyPI
Release to PyPI as you would any other module. E.g. with poetry:
poetry publish