Annotations

In Owlready, annotations are accessed with the ANNOTATIONS pseudo-dictionary. Annotations are not inherited; this is why they are not stored in the Classes or Instances, but rather in a separate dictionary.

Adding an annotation

For a given object ‘obj’ (a Class, an individual, etc), the following syntax can be used to add an annotation of a given type:

>>> from owlready import *

>>> onto = get_ontology("http://test.org/onto.owl")

>>> class Drug(Thing):
...     ontology = onto

>>> ANNOTATIONS[Drug].add_annotation(rdfs.comment, "A comment on the Drug class")

The following annotations are available by default: rdfs.comment, rdfs.isDefinedBy, rdfs.label, rdfs.seeAlso, owl.backwardCompatibleWith, owl.deprecated, owl.incompatibleWith, owl.priorVersion, owl.versionInfo. When using ANNOTATIONS, annotation classes can also be identified by a string indicating their name:

>>> ANNOTATIONS[Drug].add_annotation("comment", "A second comment on the Drug class")

The language can be specified (currently only supported for string annotations):

>>> ANNOTATIONS[Drug].add_annotation((rdfs.comment, "fr"), "Un commentaire en français")

Owlready supports annotations on Classes, Instances (=Individuals), but also relation triples.

>>> class HealthProblem(Thing):
...     ontology = onto

>>> class is_prescribed_for(Property):
...     ontology = onto
...     domain   = [Drug]
...     range    = [HealthProblem]

>>> acetaminophen = Drug("acetaminophen")

>>> pain = HealthProblem("pain")
>>> acetaminophen.is_prescribed_for.append(pain)

>>> ANNOTATIONS[acetaminophen].add_annotation("comment", "A comment on this particular drug")
>>> ANNOTATIONS[acetaminophen, is_prescribed_for, pain].add_annotation("comment", "A comment on a relation")

Special pseudo-properties are provided for annotating subclasses (owl.is_a), equivalence (owl.equivalent_to), domains (owl.domain) and ranges (owl.range).

>>> ANNOTATIONS[Drug, owl.is_a, Thing].add_annotation("comment", "A comment on an is-a relation")
>>> ANNOTATIONS[is_prescribed_for, owl.domain, Drug].add_annotation("comment", "A comment on a property domain")
>>> ANNOTATIONS[is_prescribed_for, owl.range, HealthProblem].add_annotation("comment", "A comment on a property range")

For replacing a single existing annotation of a given type by a new value:

>>> ANNOTATIONS[acetaminophen]["comment"] = "This comment replaces the first existing comment on acetaminophen"

Querying annotations

The following syntax can be used to get a list of the annotations of a given type (given as a string or an AnnotationProperty subclass):

>>> print(ANNOTATIONS[Drug][rdfs.comment])
['A comment on the Drug class', 'A second comment on the Drug class', 'Un commentaire en français']

>>> print(ANNOTATIONS[Drug][rdfs.comment, "fr"])
['Un commentaire en français']

>>> print(ANNOTATIONS[acetaminophen, is_prescribed_for, pain]["comment"])
['A comment on a relation']

>>> print(ANNOTATIONS[Drug, owl.is_a, Thing]["comment"])
['A comment on an is-a relation']

>>> print(ANNOTATIONS[Drug, owl.is_a, Thing].get_first("comment")
'A comment on an is-a relation'

Iterating through annotations

The following syntax can be used for iterating through all annotations for a given object:

>>> for annotation_property, annotation_value, annotation_lang in ANNOTATIONS[Drug].items():
...     print(annotation_property, annotation_value, annotation_lang)
comment This comment replaces all existing comment on the Drug class
comment A second comment on the Drug class
comment Un commentaire en français fr

‘annotation_lang’ defaults to an empty string if not specified.

Deleting annotations

For removing a given annotation:

>>> ANNOTATIONS[acetaminophen].del_annotation("comment", "This comment replaces all existing comment on the Drug class")

For removing all annotations of a given type:

>>> del ANNOTATIONS[acetaminophen]["comment"]

Creating a new class of annotation

The AnnotationProperty class can be subclasses to create a new class of annotation:

>>> class my_annotation(AnnotationProperty):
...     ontology = onto

You can also create a subclass of an existing annotation class:

>>> class pharmaceutical_comment(rdfs.comment):
...     ontology = onto

>>> ANNOTATIONS[acetaminophen].add_annotation(pharmaceutical_comment, "A comment related to pharmacology of acetaminophen")