2

The diagrams in https://linkml.io/linkml-model/docs/SchemaDefinition/ and https://linkml.io/linkml-model/docs/ClassDefinition/ show no operations.

Since i didn't find an add operation i am accessing the classes dict directly.

Is this approach of adding classes to a SchemaDefinition the "official" way?

'''
Created on 2023-02-20

@author: wf
'''
from meta.metamodel import Context
from linkml_runtime.linkml_model import SchemaDefinition, ClassDefinition
    
import yaml

class SiDIF2LinkML:
    """
    converter between SiDIF and LINKML
    """
    
    def __init__(self,context:Context):
        self.context=context
        
    def asYaml(self)->str:
        """
        convert my context
        """
        # https://linkml.io/linkml-model/docs/SchemaDefinition/
        sd=SchemaDefinition(id=self.context.name,name=self.context.name)
        for topic in self.context.topics.values():
            cd=ClassDefinition(name=topic.name)
            sd.classes[topic.name]=cd
            pass
        yaml_text=yaml.dump(self.context.did)
        return yaml_text
            sd.classes[topic.name]=cd
Wolfgang Fahl
  • 15,016
  • 11
  • 93
  • 186
  • Hi Wolfgang. Is it your intention to write LinkML Dataclasses directly in Python code, as opposed to writing them in YAML? If you write them in YAML, then you will be able to use the linter and generate many different kinds of artifacts, including the Python Dataclasses. – Mark Miller Feb 20 '23 at 18:11
  • Regarding operations... could those also be considered relationships? The slot that relates one or more class definition to a schema definition is `slots`, https://linkml.io/linkml-model/docs/classes/ If you expand the LinkML Source deatils at the bottom of the page, you will see a more explicit assertion of that slots's domain (a schema definition) and range (a collection of class definitions) – Mark Miller Feb 20 '23 at 18:13
  • I would like to convert my SiDIF defined models to linkML see https://github.com/WolfgangFahl/pyMetaModel/issues/14. The idea is to use linkML as an option for https://github.com/WolfgangFahl/py-yprinciple-gen which then generates Semantic MediaWiki pages according to https://www.semantic-mediawiki.org/wiki/Metadata_management#ProfiWiki – Wolfgang Fahl Feb 20 '23 at 18:28
  • The operation i was looking for is "add_class" - it's not in the SchemaDefinition class but in the SchemaView one. – Wolfgang Fahl Feb 20 '23 at 18:34

2 Answers2

1

The following code works and seems to create valid linkML yaml code.

'''
Created on 2023-02-20

@author: wf
'''
from meta.metamodel import Context
from linkml_runtime.utils.schemaview import SchemaView
from linkml_runtime.linkml_model import SchemaDefinition, ClassDefinition
from linkml.generators.linkmlgen import LinkmlGenerator

class SiDIF2LinkML:
    """
    converter between SiDIF and LINKML
    """
    
    def __init__(self,context:Context):
        self.context=context
        
    def asYaml(self)->str:
        """
        convert my context
        """
        # https://linkml.io/linkml-model/docs/SchemaDefinition/
        sd=SchemaDefinition(id=self.context.name,name=self.context.name)
        sv=SchemaView(sd)
        for topic in self.context.topics.values():
            cd=ClassDefinition(name=topic.name)
            cd.description=topic.documentation
            sv.add_class(cd)
            
            pass
      
        lml_gen=LinkmlGenerator(schema=sd,format='yaml')
        yaml_text=lml_gen.serialize()
        return yaml_text

see https://github.com/WolfgangFahl/pyMetaModel/tree/main/examples/metamodel

name: MetaModel
id: MetaModel
default_prefix: MetaModel/
classes:
  Context:
    name: Context
    description: A Context groups some topics like a Namespace/Package
    from_schema: MetaModel
  Property:
    name: Property
    description: a Property is a Feature/Attribute of a Topic
    from_schema: MetaModel
  SMW_Type:
    name: SMW_Type
    description: an SMW_Type is a data type which determines the possible values for
      that type e.g. a Boolean can hold true/false values while a Number can hold
      3.1459 or 20. A Page can hold the name of a Wiki page see https://semantic-mediawiki.org/wiki/Help:List_of_datatypes
    from_schema: MetaModel
  Topic:
    name: Topic
    description: A Topic is a Concept/Class/Thing/Entity
    from_schema: MetaModel
  Action:
    name: Action
    description: An action/function/operation to be performed
    from_schema: MetaModel
  TopicLink:
    name: TopicLink
    description: A TopicLink links two Concepts
    from_schema: MetaModel

There is still work todo to get the full model converted as shown in the plantuml diagram below. But seems to be a good start plantuml diagram of input model

Wolfgang Fahl
  • 15,016
  • 11
  • 93
  • 186
1

Yes, this is currently the canonical way to do this. The LinkML python framework generates dataclasses that intentionally avoid any behavior, including getters and setters, and this applies to the metamodel as well as any domain models. There is a valid use case for adding helper behavior for collections, we opened an issue for this here: https://github.com/linkml/linkml/issues/1302

Chris Mungall
  • 629
  • 5
  • 13