0

As contributor to https://github.com/WolfgangFahl/pyMetaModel i am running into a problem when trying out the generated linkML yaml files with different LinkML generators

While the linkML and mermaid generators seem to run fine the python code generator does not and therefore i get a 0 byte long python file when piping the result of the generator to a .py file

scripts/genexamples 
generating PlantUML for examples/family/FamilyContext
generating linkML for examples/family/FamilyContext
generating mermaid ER Diagram for examples/family/FamilyContext
generating python code for examples/family/FamilyContext
INFO:root:Default_range not specified. Default set to 'string'
ValueError: File "FamilyContext.yaml", line 3, col 17 Default prefix: FamilyContext/ is not defined
generating PlantUML for examples/teaching/TeachingSchema
generating linkML for examples/teaching/TeachingSchema
generating mermaid ER Diagram for examples/teaching/TeachingSchema
generating python code for examples/teaching/TeachingSchema
INFO:root:Default_range not specified. Default set to 'string'
ValueError: File "TeachingSchema.yaml", line 3, col 17 Default prefix: TeachingSchema/ is not defined
generating PlantUML for examples/metamodel/metamodel
generating linkML for examples/metamodel/metamodel
generating mermaid ER Diagram for examples/metamodel/metamodel
generating python code for examples/metamodel/metamodel
INFO:root:Default_range not specified. Default set to 'string'
ValueError: File "metamodel.yaml", line 3, col 17 Default prefix: MetaModel/ is not defined

How is the error ValueError: File "TeachingSchema.yaml", line 3, col 17 Default prefix: TeachingSchema/ is not defined to be fixed?

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

2 Answers2

2

The default prefix for a schema is defined at the top level of the yaml. I don't think that any of the tooling would care about the order, but as a matter of convention it tends to follow the prefix listing, like in this example from models section of the documentation:

id: https://w3id.org/linkml/examples/personinfo
name: personinfo
description: |-
  Information about people, based on [schema.org](http://schema.org)
license: https://creativecommons.org/publicdomain/zero/1.0/
default_curi_maps:
  - semweb_context
imports:
  - linkml:types
prefixes:
  personinfo: https://w3id.org/linkml/examples/personinfo/
  linkml: https://w3id.org/linkml/
  schema: http://schema.org/
  rdfs: http://www.w3.org/2000/01/rdf-schema#
  prov: http://www.w3.org/ns/prov#
default_prefix: personinfo
default_range: string
Kevin Schaper
  • 261
  • 2
  • 3
  • so prefixes is a mandatory section and there must be a default-prefix. Looks like the same hold true for default_range. Is there a mandatory flag in the meta model that shows this? – Wolfgang Fahl Feb 23 '23 at 06:38
  • please amend your answer according to the OBO chat mentioning the Schemabuilder so that i can accept it. – Wolfgang Fahl Feb 23 '23 at 19:14
1

The improved code is using the SchemaBuilder as suggested by Kevin Schaper. The result is better and valid python code an xslx files can be generated from it see https://github.com/WolfgangFahl/pyMetaModel/tree/main/examples

'''
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, SlotDefinition
from linkml.generators.linkmlgen import LinkmlGenerator
from linkml_runtime.linkml_model import Prefix
from linkml.utils.schema_builder import SchemaBuilder


class SiDIF2LinkML:
    """
    converter between SiDIF and LINKML
    """
    
    def __init__(self,context:Context):
        self.context=context
        
    def asYaml(self,common_property_slots:bool=True,delim="_")->str:
        """
        convert my context
        
        Args:
            common_property_slots(bool): if True reuse slots 
            
        Returns:
            str: the yaml markup
        
        """
        context=self.context
        sb=SchemaBuilder(id=context.name,name=context.name)
        # https://linkml.io/linkml-model/docs/SchemaDefinition/
        sb.add_defaults()
        sd=sb.schema
        sv=SchemaView(sd)
        if hasattr(context,"copyright"):
            copyright_str=f" copyright {context.copyright}"
        else:
            copyright_str=""
        if hasattr(context,"master"):
            master=context.master
        else:
            master="http://example.com"
        uri=f"{master}/{context.name}"
        for topic in self.context.topics.values():
            cd=ClassDefinition(name=topic.name)
            cd.description=topic.documentation
            sv.add_class(cd)
            for prop in topic.properties.values():
                slot=None
                if common_property_slots:
                    qname=prop.name
                    if prop.name in sd.slots:
                        slot=sd.slots[prop.name]
                        slot.description+=","+prop.documentation
                else:
                    qname=f"{topic.name}{delim}{prop.name}"
                if slot is None:
                    slot=SlotDefinition(name=qname)
                    if hasattr(prop,"documentation"):
                        slot.description=prop.documentation  
                    slot.range="string"       
                    sv.add_slot(slot)
                cd.attributes[qname]=slot
                pass
            
            pass
      
        lml_gen=LinkmlGenerator(schema=sd,format='yaml')
        yaml_text=lml_gen.serialize()
        return yaml_text
Wolfgang Fahl
  • 15,016
  • 11
  • 93
  • 186