Overview

OnToCode (Ontology To Code) is a Python package for ontology-to-code transformation. With OnToCode, you can instantiate templates with data queried from ontologies.

OnToCode´s purpose is to provide software developers with a configurable, output-format agnostic tool to generate code (and potentially other artifacts) from ontologies. This Python package is a framework that connects a library that loads ontologies into Python objects and can run SPARQL-queries against them, with templates libraries (currently just Jinja2) and a framework to transform the query results into template arguments.

Guidepost

This document provides information about OnToCode´s requirements, build instructions for the documentation, a quick guide to OnToCode´s usage, as well as copyright and licensing information.

Further information for users and developers can be found in the documentation, hosted on Read the Docs.

Example

The subdirectory example contains an elaborate example of OnToCode use. Instructions on how to try out the example are given in the example project’s README file.

Requirements

OnToCode was developed and tested using Python 3.6. Lower version of Python 3 might work as well. It depends on the Python packages Owlready2 and RDFLib, and optionally on the Python package Jinja2.

Building the Documentation

Run python setup.py docs to build the documentation. After a successful build, the documentation can be found in build/sphinx/html with index.html as the entry page.

Quick Guide

This is a short introduction to OnToCode. We go through the code of a self-contained example that can be copied into a file and run in a Python 3 environment that has OnToCode, its dependencies, and Jinja2 installed.

We start by importing OnToCode:

import ontocode

To tell OnToCode which ontology to load, we create an URLOntologyLocator to load the example ontology http://www.w3.org/TR/2003/PR-owl-guide-20031209/food# from https://www.w3.org/TR/owl-guide/food.rdf:

url = 'https://www.w3.org/TR/owl-guide/food.rdf'
locator = ontocode.URLOntologyLocator(url)

Next, we set up a SPARQL-Query that extracts the desired data:

query_string = '''SELECT ?type
WHERE {
    ?type rdfs:subClassOf
          <http://www.w3.org/TR/2003/PR-owl-guide-20031209/food##Seafood>
}
ORDER BY ASC(?type)'''
query = ontocode.Query(query_string)

OnToCode runs our SPARQL-query against the loaded ontology. The query yields a list of dictionaries with query variable names as keys and bound Owlready2 objects for the respective result rows as values. We need to convert this result into the form that our template expects as input. This is done with result processors:

processor_chain = [ontocode.ObjectNameProcessor(),
                   ontocode.list_of_dicts_to_dict_of_lists]
template_input = ontocode.TemplateInput(query, processor_chain)

During template instantiation, the first processor is applied to the result of the query and subsequent processors are applied, in order, to the output of their respective predecessor.

ObjectNameProcessor converts the Owlready2 objects in the dictionaries to their names, so we have a list of dictionaries with variable names as keys and object names as values.

list_of_dicts_to_dict_of_lists() turns our list of dictionaries into adictionary of lists by taking the keys of the dictionaries and assigning to each a list of all values that were previously mapped to that key in the individual dictionaries.

Then we pass our query and the list of processors, the processor chain, into TemplateInput´s constructor.

Next, we need a template:

template_string = '{% for t in type %}{{t}}{% endfor %}'
template = ontocode.Jinja2Template.from_string(template_string)

For this example, we content ourselves with a simple Jinja2Template.

Now, we have everything to instantiate our template and we do it with an Instantiation object:

instantiation = ontocode.Instantiation([locator], template, [template_input])
result = instantiation.execute()

assert 'FishShellfish' == result[0]

Type or paste all code blocks of this section into a file, e.g. ontocode.py, and run the script with python ontocode.py. Make sure that you are using Python 3 and that OnToCode as well as Jinja2 are on the path. When run, the script should output nothing (apart from an Owlready2 related warning).

As is the nature of a short introduction, we glossed over a lot of details. For a full explanation of how to use OnToCode consult the Reference.