Annotations#
Background#
The LinkML model provides a fixed set of metamodel slots which can be applied to any schema element.
Examples of these are:
description - a human readable description of the element
comments - a human readable comment about the element
aliases - a set of alternative names for the element
deprecated - a boolean flag indicating that the element is deprecated
seeAlso - a set of URIs that provide additional information about the element
If you attempt to assign a slot that is not in the metamodel, you will get an error. For example,
if you wanted to add a review
slot to the Person
class like this:
classes:
Person:
description: A person, living or dead
review: A very useful class that is well defined
attributes:
id: ...
This will result in an error, because review
is not a metamodel slot.
This conformance to a single metamodel can be useful for ensuring consistency and interoperability among LinkML schemas. However, it can be too constraining in some cases. To get around this, the LinkML metamodel has a generic annotations slot that can be used to assign arbitrary tags and values to any schema element.
Adding your own annotations#
In the above case, we can add the review
annotation to the Person
class like this:
classes:
Person:
annotations:
review: A very useful class that is well defined
...
Note that in the underlying metamodel, the range of annotations is
an Annotation class, which has two slots: tag
and value
. This is
usually written in compact form as tag: value
, as in the above.
Note also that prior to LinkML 1.6, the range of the annotation value was string
, but in 1.6 and higher,
the range can be any object.
Annotation validation#
By default, all annotation tags and values are valid. Feel free to add whatever annotations you like to any schema element - classes, enums, permissible values, slots, even schemas themselves.
However, if you want to restrict the set of valid annotations, you can do this starting from LinkMK 1.6, where you can treat annotation tags as if they were slots in your own metamodel extension.
This is done by adding an instantiates slot-value assignment onto any schema element. The range of
the instantiates
slot is a uriorcurie
that references a class that serves as a metamodel extension class.
For example, given our example schema fragment, we can add an instantiates
slot to the Person
class,
stating that this class is an instance of the Reviewable
metamodel extension class:
classes:
Person:
instantiates:
- mymetamodel:Reviewable
annotations:
review: A very useful class that is well defined
...
This metaclass extension can live in the same schema, or in a different schema. This is why they are referenced
by uriorcurie
rather than a local name.
The Reviewable
class might be defined as follows:
id: https://example.org/mymetamodel/
name: mymetamodel
...
classes:
Reviewable:
class_uri: mymetamodel:Reviewable
attributes:
review:
description: an expert review of a schema element
range: string
This can be thought of as a schema element mixin class - the class defines the extra slots that can be attached to schema elements via annotations.
Other schema elements can also instantiate the Reviewable
class:
classes:
Person:
instantiates:
- mymetamodel:Reviewable
annotations:
review: A very useful class that is well defined
...
attributes:
name:
description: the name of a person
instantiates: mymetamodel:Reviewable
annotations:
review: A very useful attribute that is well defined
...
Note that here the attributes
section of the Person
definition is the attributes that an
instance of Person
may have. The annotations
section pertains to the class Person, not instances.
Validation of annotations#
If a schema element does not instantiate a metamodel extension class, then any annotation tag is valid.
(this is already the case for all pre 1.6 schemas, since the instantiates
slot is not defined in previous
versions of the metamodel).
If a schema element does instantiate a metamodel extension class, then the set of valid annotation tags should conform to the slots defined in the metamodel extension class, as if the annotation tags were first-class slots, and instantiates value was a mixin.
However, this is not yet supported in the current LinkML validator, so using instantiates
indicates your
intent, but does not yet enforce validation.
Other uses of instantiates#
The instantiates
slot can also be used constrain rather than extend.
For example, to define a strict metamodel element that must have a description:
id: https://example.org/mymetamodel/
name: mymetamodel
...
classes:
StrictElement:
class_uri: mymetamodel:StrictClassDefinition
slot_usage:
description:
required: true
Any schema element that instantiates StrictElement
must have a description:
classes:
Person:
instantiates:
- mymetamodel:StrictElement
description: A person, living or dead ## must be provided