Exemplo n.º 1
0
 def gen_references(self) -> str:
     """ Generate python type declarations for all identifiers (primary keys)
     """
     rval = []
     for cls in self._sort_classes(self.schema.classes.values()):
         if not cls.imported_from:
             pkeys = self.primary_keys_for(cls)
             if pkeys:
                 for pk in pkeys:
                     classname = camelcase(cls.name) + camelcase(
                         self.aliased_slot_name(pk))
                     # If we've got a parent slot and the range of the parent is the range of the child, the
                     # child slot is a subclass of the parent.  Otherwise, the child range has been overridden,
                     # so the inheritence chain has been broken
                     parent_pk = self.class_identifier(
                         cls.is_a) if cls.is_a else None
                     parent_pk_slot = self.schema.slots[
                         parent_pk] if parent_pk else None
                     pk_slot = self.schema.slots[pk]
                     if parent_pk_slot and (parent_pk_slot.name == pk
                                            or pk_slot.range
                                            == parent_pk_slot.range):
                         parents = self.class_identifier_path(
                             cls.is_a, False)
                     else:
                         parents = self.slot_range_path(pk_slot)
                     parent_cls = 'extended_' + parents[-1] if parents[
                         -1] in ['str', 'float', 'int'] else parents[-1]
                     rval.append(
                         f'class {classname}({parent_cls}):\n\tpass')
                     break  # We only do the first primary key
     return '\n\n\n'.join(rval)
Exemplo n.º 2
0
    def _link(self,
              obj: Optional[Element],
              *,
              after_link: str = None,
              use_desc: bool = False,
              add_subset: bool = True) -> str:
        """ Create a link to ref if appropriate.

        @param ref: the name or value of a class, slot, type or the name of a built in type.
        @param after_link: Text to put between link and description
        @param use_desc: True means append a description after the link if available
        @param add_subset: True means add any subset information that is available
        @return:
        """
        nl = '\n'
        if obj is None or not self.is_secondary_ref(obj.name):
            return self.bbin(obj)
        if isinstance(obj, SlotDefinition):
            link_name = ((be(obj.domain) + '➞')
                         if obj.alias else '') + self.aliased_slot_name(obj)
            link_ref = underscore(obj.name)
        elif isinstance(obj, TypeDefinition):
            link_name = camelcase(obj.name)
            link_ref = f"types/{link_name}"
        elif isinstance(obj, ClassDefinition):
            link_name = camelcase(obj.name)
            link_ref = camelcase(link_name)
        else:
            link_name = obj.name
            link_ref = link_name
        desc = self.desc_for(obj, use_desc)
        return f'[{link_name}]' \
               f'({link_ref}.{self.format})' + \
                 (f' {after_link} ' if after_link else '') + (f' - {desc.split(nl)[0]}' if desc else '')
Exemplo n.º 3
0
    def end_class(self, cls: ClassDefinition) -> None:
        if cls.is_a:
            self._add_constraint(self.namespaces.uri_for(camelcase(cls.is_a) + "_t"))
        for mixin in cls.mixins:
            if self._class_has_expressions(mixin):
                self._add_constraint(self.namespaces.uri_for(camelcase(mixin) + "_t"))
        if cls.name in self.synopsis.applytorefs:
            for applyto in self.synopsis.applytorefs[cls.name].classrefs:
                if self._class_has_expressions(applyto):
                    self._add_constraint(self.namespaces.uri_for(camelcase(applyto) + '_t'))

        self.shape.closed = True
        self.shape.extra = [RDF.type]
        if self.shape.expression:
            # TODO: Figure out how to label a single triple expression
            if isinstance_(self.shape.expression, tripleExprLabel):
                self.shape.expression = EachOf(expressions=[self.shape.expression, wildcard(None)])
            self.shape.expression.id = self.namespaces.uri_for(camelcase(cls.name) + "_t")
        else:
            self.shape.expression = wildcard(self.namespaces.uri_for(camelcase(cls.name) + "_t"))

        if self.class_identifier(cls):
            self.shape.extra = [RDF.type]
            type_constraint = TripleConstraint()
            type_constraint.predicate = RDF.type
            type_constraint.valueExpr = NodeConstraint(values=[IRIREF(self.namespaces.uri_for(cls.class_uri))])
            if not self.shape.expression:
                self.shape.expression = type_constraint
            else:
                self.shape.expression = EachOf(expressions=[self.shape.expression, type_constraint])

        shapeExpr = self.shape
        shapeExpr.id = self._shape_iri(cls.name)
        self.shapes.append(shapeExpr)
Exemplo n.º 4
0
 def _visit(self, node: Any) -> Optional[Any]:
     if isinstance(node, (YAMLRoot, dict)):
         if isinstance(node, YAMLRoot):
             node = self._add_type(node)
         for k, v in list(node.items()):
             if v:
                 new_v = self._visit(v)
                 if new_v is not None:
                     node[k] = new_v
     elif isinstance(node, list):
         for i in range(0, len(node)):
             new_v = self._visit(node[i])
             if new_v is not None:
                 node[i] = new_v
     elif isinstance(node, set):
         for v in list(node):
             new_v = self._visit(v)
             if new_v is not None:
                 node.remove(v)
                 node.add(new_v)
     elif isinstance(node, ClassDefinitionName):
         return ClassDefinitionName(camelcase(node))
     elif isinstance(node, SlotDefinitionName):
         return SlotDefinitionName(underscore(node))
     elif isinstance(node, TypeDefinitionName):
         return TypeDefinitionName(underscore(node))
     elif isinstance(node, SubsetDefinitionName):
         return SubsetDefinitionName(underscore(node))
     elif isinstance(node, ElementName):
         return ClassDefinitionName(camelcase(node)) if node in self.schema.classes else \
             SlotDefinitionName(underscore(node)) if node in self.schema.slots else \
             SubsetDefinitionName(camelcase(node)) if node in self.schema.subsets else \
             TypeDefinitionName(underscore(node)) if node in self.schema.types else None
     return None
Exemplo n.º 5
0
 def visit_class(self, cls: ClassDefinition) -> bool:
     self.classtab.writerow({
         'Class Name':
         camelcase(cls.name),
         'Parent Class':
         camelcase(cls.is_a) if cls.is_a else '',
         'YAML Class Name':
         cls.name,
         'Description':
         cls.description
     })
     return True
Exemplo n.º 6
0
    def test_formats(self):
        self.assertEqual("ThisIsIt", camelcase("this is it"))
        self.assertEqual("ThisIsIT", camelcase("  this   is iT   "))
        self.assertEqual("IBeY", camelcase("i be y "))
        self.assertEqual("ThisIsIt", camelcase("This__is_it"))

        self.assertEqual("this_is_it", underscore(" this is it "))
        self.assertEqual("this_is_it", underscore("this   is   it"))

        self.assertEqual("thisIsIt", lcamelcase("   this   is\t  it\n"))

        self.assertEqual('abc', be('  abc\n'))
        self.assertEqual('', be(None))
        self.assertEqual('', be('   '))
Exemplo n.º 7
0
    def gen_typedefs(self) -> str:
        """ Generate python type declarations for all defined types """
        rval = []
        for typ in self.schema.types.values():
            if not typ.imported_from:
                typname = camelcase(typ.name)
                desc = f'\n\t""" {typ.description} """' if typ.description else ''

                if typ.typeof:
                    parent_typename = camelcase(typ.typeof)
                    rval.append(f'class {typname}({parent_typename}):{desc}\n\t{self.gen_type_meta(typ)}\n\n')
                else:
                    base_base = typ.base.rsplit('.')[-1]
                    rval.append(f'class {typname}({base_base}):{desc}\n\t{self.gen_type_meta(typ)}\n\n')
        return '\n'.join(rval)
Exemplo n.º 8
0
 def class_or_type_name(self, name: str) -> str:
     """
     Return the camelcase representation of clsname if it is a valid class or type.  Prepend "Unknown"
     if the name isn't valid
     """
     if name in self.schema.classes:
         return camelcase(name)
     elif name in self.schema.types:
         typ = self.schema.types[cast(TypeDefinitionName, name)]
         if typ.typeof:
             return camelcase(name)
         else:
             return typ.base
     else:
         return "Unknown_" + camelcase(name)
Exemplo n.º 9
0
    def gen_enum(self, enum: EnumDefinition) -> str:
        enum_name = camelcase(enum.name)
        return f'''
class {enum_name}(EnumDefinitionImpl):
    {self.gen_enum_comment(enum)}
    {self.gen_enum_description(enum, enum_name)}
'''.strip()
Exemplo n.º 10
0
 def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str,
                      slot: SlotDefinition) -> None:
     qual = 'repeated ' if slot.multivalued else 'optional ' if not slot.required or slot.key else ''
     slotname = lcamelcase(aliased_slot_name)
     slot_range = camelcase(slot.range)
     self.relative_slot_num += 1
     print(f"  {qual}{slotname} {slot_range} = {self.relative_slot_num}")
Exemplo n.º 11
0
 def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str, slot: SlotDefinition) -> None:
     slotrange = camelcase(slot.range) if slot.range in self.schema.classes or slot.range in self.schema.types else "String"
     if slot.multivalued:
         slotrange = f"[{slotrange}]"
     if slot.required:
         slotrange = slotrange + '!'
     print(f"    {lcamelcase(aliased_slot_name)}: {slotrange}")
Exemplo n.º 12
0
 def gen_type_meta(self, typ: TypeDefinition) -> str:
     type_class_uri = self.namespaces.uri_for(typ.uri)
     if type_class_uri:
         type_python_uri = self.namespaces.curie_for(type_class_uri,
                                                     default_ok=False,
                                                     pythonform=True)
         type_class_curie = self.namespaces.curie_for(type_class_uri,
                                                      default_ok=False,
                                                      pythonform=False)
     else:
         type_python_uri = None
         type_class_curie = None
     if type_class_curie:
         type_class_curie = f'"{type_class_curie}"'
     type_class_uri = type_python_uri if type_python_uri else f'URIRef("{type_class_uri}")'
     type_model_uri = self.namespaces.uri_or_curie_for(
         self.schema.default_prefix, camelcase(typ.name))
     if ':/' in type_model_uri:
         type_model_uri = f'URIRef("{type_model_uri}")'
     else:
         ns, ln = type_model_uri.split(':', 1)
         ln_suffix = f".{ln}" if ln.isidentifier() else f'["{ln}"]'
         type_model_uri = f"{ns.upper()}{ln_suffix}"
     vars = [
         f'type_class_uri = {type_class_uri}',
         f'type_class_curie = {type_class_curie}',
         f'type_name = "{typ.name}"', f'type_model_uri = {type_model_uri}'
     ]
     return "\n\t".join(vars)
Exemplo n.º 13
0
 def add_element(self, e: Element) -> None:
     if e.imported_from:
         if str(e.imported_from) == biolinkml.METATYPE_URI:
             # TODO: figure out how to make this sort of stuff part of the model
             self.v.setdefault(types.__name__,
                               set()).add(camelcase(e.name))
         elif str(e.imported_from) == biolinkml.BIOLINK_MODEL_URI:
             self.v.setdefault(biolinkml.BIOLINK_MODEL_PYTHON_LOC,
                               set()).add(camelcase(e.name))
         elif e.imported_from.__contains__('://'):
             raise ValueError(
                 f"Cannot map {e.imported_from} into a python import statement"
             )
         else:
             self.v.setdefault(types.__name__,
                               set()).add(camelcase(e.name))
Exemplo n.º 14
0
 def gen_slot(self, slot: SlotDefinition) -> str:
     python_slot_name = underscore(slot.name)
     slot_uri, slot_curie = self.python_uri_for(slot.slot_uri)
     slot_model_uri, slot_model_curie = \
         self.python_uri_for(self.namespaces.uri_or_curie_for(self.schema.default_prefix, python_slot_name))
     domain = camelcase(
         slot.domain) if slot.domain and not self.schema.classes[
             slot.domain].mixin else "None"
     # Going to omit the range on keys where the domain isn't specified (for now)
     if slot.domain is None and (slot.key or slot.identifier):
         rnge = "URIRef"
     else:
         rnge, _ = self.range_cardinality(
             slot,
             self.schema.classes[slot.domain] if slot.domain else None,
             True)
     if slot.mappings:
         map_texts = [
             self.namespaces.curie_for(self.namespaces.uri_for(m),
                                       default_ok=True,
                                       pythonform=True)
             for m in slot.mappings if m != slot.slot_uri
         ]
     else:
         map_texts = []
     if map_texts:
         mappings = ', mappings = [' + ', '.join(map_texts) + ']'
     else:
         mappings = ''
     pattern = f",\n                   pattern=re.compile(r'{slot.pattern}')" if slot.pattern else ""
     return f"""slots.{python_slot_name} = Slot(uri={slot_uri}, name="{slot.name}", curie={slot_curie},
Exemplo n.º 15
0
    def visit_type(self, typ: TypeDefinition) -> None:
        with open(self.dir_path(typ), 'w') as typefile:
            with redirect_stdout(typefile):
                full_path = sfx(self.namespaces._base) + (sfx(
                    typ.imported_from) if typ.imported_from else '')
                type_curie = self.namespaces.uri_or_curie_for(
                    full_path, camelcase(typ.name))
                type_uri = self.namespaces.uri_for(type_curie)
                self.frontmatter(
                    **{
                        'parent': 'Types',
                        'title': type_curie,
                        'grand_parent': self.doc_root_title,
                        'layout': 'default'
                    })
                self.element_header(typ, typ.name, type_curie, type_uri)

                print("|  |  |  |")
                print("| --- | --- | --- |")
                if typ.typeof:
                    print(
                        f"| Parent type | | {self.class_type_link(typ.typeof)} |"
                    )
                print(f"| Root (builtin) type | | **{typ.base}** |")
                if typ.repr:
                    print(f"| Representation | | {typ.repr} |")
Exemplo n.º 16
0
    def class_identifier_path(self, cls_or_clsname: Union[str,
                                                          ClassDefinition],
                              force_non_key: bool) -> List[str]:
        """
        Return the path closure to a class identifier if the class has a key and force_non_key is false otherwise
        return a dictionary closure.

        :param cls_or_clsname: class definition
        :param force_non_key: True means inlined even if the class has a key
        :return: path
        """
        cls = cls_or_clsname if isinstance(cls_or_clsname, ClassDefinition) \
            else self.schema.classes[cast(ClassDefinitionName, cls_or_clsname)]

        # Determine whether the class has a key
        identifier_slot = None
        if not force_non_key:
            identifier_slot = self.class_identifier(cls, keys_count=True)

        # No key or inlined, its closure is a dictionary
        if identifier_slot is None:
            return ['dict', self.class_or_type_name(cls.name)]

        # We're dealing with a reference
        pathname = camelcase(cls.name + ' ' +
                             self.aliased_slot_name(identifier_slot))
        if cls.is_a:
            parent_identifier_slot = self.class_identifier(cls.is_a,
                                                           keys_count=True)
            if parent_identifier_slot:
                return self.class_identifier_path(cls.is_a, False) + [pathname]
        return self.slot_type_path(identifier_slot) + [pathname]
Exemplo n.º 17
0
    def gen_class_meta(self, cls: ClassDefinition) -> str:
        class_class_uri = self.namespaces.uri_for(cls.class_uri)
        if class_class_uri:
            cls_python_uri = self.namespaces.curie_for(class_class_uri,
                                                       default_ok=False,
                                                       pythonform=True)
            class_class_curie = self.namespaces.curie_for(class_class_uri,
                                                          default_ok=False,
                                                          pythonform=False)
        else:
            cls_python_uri = None
            class_class_curie = None
        if class_class_curie:
            class_class_curie = f'"{class_class_curie}"'
        class_class_uri = cls_python_uri if cls_python_uri else f'URIRef("{class_class_uri}")'
        class_model_uri = self.namespaces.uri_or_curie_for(
            self.schema.default_prefix or "DEFAULT_", camelcase(cls.name))
        if ':/' in class_model_uri:
            class_model_uri = f'URIRef("{class_model_uri}")'
        else:
            ns, ln = class_model_uri.split(':', 1)
            class_model_uri = f"{ns.upper()}.{ln}"

        vars = [
            f'class_class_uri: ClassVar[URIRef] = {class_class_uri}',
            f'class_class_curie: ClassVar[str] = {class_class_curie}',
            f'class_name: ClassVar[str] = "{cls.name}"',
            f'class_model_uri: ClassVar[URIRef] = {class_model_uri}'
        ]
        if cls.string_template:
            vars.append('')
            vars.append(
                f'string_template: ClassVar[str] = "{cls.string_template}"')
        return "\n\t".join(vars)
Exemplo n.º 18
0
    def visit_slot(self, slot_name: str, slot: SlotDefinition) -> None:
        """ Add a slot definition per slot

        @param slot_name:
        @param slot:
        @return:
        """
        # Note: We use the raw name in OWL and add a subProperty arc
        slot_uri = self._prop_uri(slot.name)
        self._add_element_properties(slot_uri, slot)
        self.graph.add(
            (slot_uri, RDF.type,
             OWL.ObjectProperty if slot.inherited else OWL.AnnotationProperty))
        self.graph.add((slot_uri, RDF.type,
                        self.metamodel.namespaces[METAMODEL_LOCAL_NAME][
                            camelcase('slot definition')]))
        self.graph.add((slot_uri, RDFS.range, self._range_uri(slot)))
        self.graph.add((slot_uri, RDFS.domain, self._class_uri(slot.domain)))

        # Parent slots
        if slot.is_a:
            self.graph.add(
                (slot_uri, RDFS.subPropertyOf, self._prop_uri(slot.is_a)))
        for mixin in slot.mixins:
            self.graph.add(
                (slot_uri, RDFS.subPropertyOf, self._prop_uri(mixin)))
        if slot.name in self.synopsis.applytorefs:
            for appl in self.synopsis.applytorefs[slot.name].slotrefs:
                self.graph.add(
                    (slot_uri, RDFS.subClassOf, self._prop_uri(appl)))
Exemplo n.º 19
0
 def visit_class(self, cls: ClassDefinition) -> bool:
     etype = 'interface' if (cls.abstract
                             or cls.mixin) and not cls.mixins else 'type'
     mixins = ', '.join([camelcase(mixin) for mixin in cls.mixins])
     print(f"{etype} {camelcase(cls.name)}" +
           (f" implements {mixins}" if mixins else ""))
     print("  {")
     return True
Exemplo n.º 20
0
 def adjust_slot(self, slot: SlotDefinition) -> None:
     if slot.range in self.schema.classes:
         slot.range = ClassDefinitionName(camelcase(slot.range))
     elif slot.range in self.schema.slots:
         slot.range = SlotDefinitionName(underscore(slot.range))
     elif slot.range in self.schema.types:
         slot.range = TypeDefinitionName(underscore(slot.range))
     slot.slot_uri = self.namespaces.uri_for(slot.slot_uri)
Exemplo n.º 21
0
 def enum_identifier_path(
         self, enum_or_enumname: Union[str, EnumDefinition]) -> List[str]:
     """ Return an enum_identifier path """
     return [
         'str',
         camelcase(enum_or_enumname.name if isinstance(
             enum_or_enumname, EnumDefinition) else enum_or_enumname)
     ]
Exemplo n.º 22
0
 def dir_path(
         self, obj: Union[ClassDefinition, SlotDefinition,
                          TypeDefinition]) -> str:
     filename = self.formatted_element_name(obj) if isinstance(obj, ClassDefinition) \
         else underscore(obj.name) if isinstance(obj, SlotDefinition) \
         else camelcase(obj.name)
     subdir = '/types' if isinstance(obj, TypeDefinition) else ''
     return f'{self.directory}{subdir}/{filename}.md'
Exemplo n.º 23
0
 def visit_class(self, cls: ClassDefinition) -> bool:
     if cls.abstract:
         return False
     self.clsobj = JsonObj(title=camelcase(cls.name),
                           type='object',
                           properties=JsonObj(),
                           description=be(cls.description))
     return True
Exemplo n.º 24
0
    def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str,
                         slot: SlotDefinition) -> None:
        if slot.range in self.schema.classes and slot.inlined:
            rng = f"#/definitions/{camelcase(slot.range)}"
        elif slot.range in self.schema.types:
            rng = self.schema.types[slot.range].base
        else:
            # note we assume string for non-lined complex objects
            rng = "string"

        # translate to json-schema builtins
        if rng == 'int':
            rng = 'integer'
        elif rng == 'Bool':
            rng = 'boolean'
        elif rng == 'str':
            rng = 'string'
        elif rng == 'float' or rng == 'double':
            rng = 'number'
        elif not rng.startswith('#'):
            # URIorCURIE, etc
            rng = 'string'

        if slot.inlined:
            # If inline we have to include redefined slots
            ref = JsonObj()
            ref['$ref'] = rng
            if slot.multivalued:
                prop = JsonObj(type="array", items=ref)
            else:
                prop = ref
        else:
            if slot.multivalued:
                prop = JsonObj(type="array", items={'type': rng})
            else:
                prop = JsonObj(type=rng)
        if slot.description:
            prop.description = slot.description
        if slot.required:
            self.clsobj.required.append(underscore(aliased_slot_name))

        self.clsobj.properties[underscore(aliased_slot_name)] = prop
        if self.topCls is not None and camelcase(self.topCls) == camelcase(cls.name) or \
                self.topCls is None and cls.tree_root:
            self.schemaobj.properties[underscore(aliased_slot_name)] = prop
Exemplo n.º 25
0
 def _class_or_type_uri(self, item: Union[TypeDefinition, ClassDefinition, ElementName],
                        suffix: Optional[str] = '') -> URIorCURIE:
     if isinstance(item, (TypeDefinition, ClassDefinition)):
         cls_or_type = item
     else:
         cls_or_type = self.class_or_type_for(item)
     return self.namespaces.uri_for(
         self.namespaces.uri_or_curie_for(self.schema_defaults[cls_or_type.from_schema],
                                          camelcase(cls_or_type.name) + suffix))
Exemplo n.º 26
0
    def visit_class(self, cls: ClassDefinition) -> bool:
        if self.gen_classes and cls.name not in self.gen_classes:
            return False
        with open(self.dir_path(cls), 'w') as clsfile:
            with redirect_stdout(clsfile):
                self.frontmatter(f"Class: {cls.name}")
                self.para(be(cls.description))

                class_curi = self.namespaces.uri_or_curie_for(self.namespaces._base, camelcase(cls.name))
                class_uri = self.namespaces.uri_for(class_curi)
                print(f'URI: [{class_curi}]({class_uri})')
                print()
                if self.image_directory:
                    yg = YumlGenerator(self)
                    yg.serialize(classes=[cls.name], directory=self.image_directory, load_image=not self.noimages)
                    img_url = os.path.join('images', os.path.basename(yg.output_file_name))
                else:
                    yg = YumlGenerator(self)
                    img_url = yg.serialize(classes=[cls.name])\
                        .replace('[', '\\[').replace('?', '%3F').replace(' ', '%20')

                print(f'![img]({img_url})')
                self.mappings(cls)

                self.header(2, 'Inheritance')
                if cls.is_a is not None:
                    self.bullet(f' is_a: {self.class_link(cls.is_a, use_desc=True)}')
                for mixin in cls.mixins:
                    self.bullet(f' mixin: {self.class_link(mixin, use_desc=True)}')

                self.header(2, 'Children')
                if cls.name in self.synopsis.isarefs:
                    for child in sorted(self.synopsis.isarefs[cls.name].classrefs):
                        self.bullet(f'{self.class_link(child, use_desc=True)}')
                if cls.name in self.synopsis.mixinrefs:
                    for mixin in sorted(self.synopsis.mixinrefs[cls.name].classrefs):
                        self.bullet(f'{self.class_link(mixin, use_desc=True, after_link="(mixin)")}')

                if cls.name in self.synopsis.classrefs:
                    self.header(2, 'Used by')
                    for sn in sorted(self.synopsis.classrefs[cls.name].slotrefs):
                        slot = self.schema.slots[sn]
                        if slot.range == cls.name:
                            self.bullet(f' **{self.class_link(slot.domain)}** '
                                        f'*{self.slot_link(slot, add_subset=False)}*{self.predicate_cardinality(slot)}  '
                                        f'**{self.class_type_link(slot.range)}**')

                self.header(2, 'Fields')
                for sn in sorted(cls.slots):
                    self.slot_field(cls, self.schema.slots[sn])

                for slot in sorted(self.all_slots(cls), key=lambda s: s.name):
                    if slot.name not in cls.slots:
                        self.slot_field(cls, slot)

        return True
    def visit_type(self, typ: TypeDefinition) -> None:
        """
        Visit a given type definition and write the following properties in Markdown,
        - Frontmatter
        - Description
        - Domain and Range constraints
        - Parents
        - Children
        - Used by

        Parameters
        ----------
        typ: biolinkml.meta.TypeDefinition
            A TypeDefinition

        """
        with open(self.dir_path(typ), 'w') as typefile:
            with redirect_stdout(typefile):
                full_path = sfx(self.namespaces._base) + (sfx(
                    typ.imported_from) if typ.imported_from else '')
                type_curie = self.namespaces.uri_or_curie_for(
                    full_path, camelcase(typ.name))
                type_uri = self.namespaces.uri_for(type_curie)

                if type_curie.startswith(
                        'https://w3id.org/biolink/vocab/biolinkml:types/'):
                    ref = type_curie.split('/')[-1]
                    type_uri = f"https://biolink.github.io/biolinkml/docs/types/{ref}"
                    type_curie = f"metatype:{ref}"
                elif type_uri.startswith('https://w3id.org/biolink/vocab/'):
                    ref = type_curie.split('/')[-1]
                    type_uri = f"https://w3id.org/biolink/vocab/types/{ref}"
                if typ.imported_from and 'biolinkml:types' in typ.imported_from:
                    parent = 'Built-in Types'
                else:
                    parent = 'Defined Types'
                self.frontmatter(
                    **{
                        'parent': parent,
                        'grand_parent': 'Types',
                        'title': type_curie,
                        'layout': 'default'
                    })
                self.element_header(typ, typ.name, type_curie, type_uri)

                print("|  |  |  |")
                print("| --- | --- | --- |")
                if typ.typeof:
                    print(
                        f"| Parent type | | {self.class_type_link(typ.typeof)} |"
                    )
                print(f"| Root (builtin) type | | **{typ.base}** |")
                if typ.repr:
                    print(f"| Representation | | {typ.repr} |")
Exemplo n.º 28
0
 def gen_references(self) -> str:
     """ Generate python type declarations for all identifiers (primary keys)
     """
     rval = []
     for cls in self.schema.classes.values():
         if not cls.imported_from:
             pkeys = self.primary_keys_for(cls)
             if pkeys:
                 for pk in pkeys:
                     classname = camelcase(cls.name) + camelcase(
                         self.aliased_slot_name(pk))
                     if cls.is_a and self.class_identifier(cls.is_a):
                         parents = self.class_identifier_path(
                             cls.is_a, False)
                     else:
                         parents = self.slot_type_path(
                             self.schema.slots[pk])
                     rval.append(
                         f'class {classname}({parents[-1]}):\n\tpass')
                     break  # We only do the first primary key
     return '\n\n\n'.join(rval)
Exemplo n.º 29
0
 def add_element(self, e: Element) -> None:
     if e.imported_from:
         if str(e.imported_from) == biolinkml.METATYPE_URI:
             # TODO: figure out how to make this sort of stuff part of the model
             self.v.setdefault(types.__name__,
                               set()).add(camelcase(e.name))
         elif e.imported_from.__contains__('://'):
             raise (
                 NotImplementedError,
                 f"Cannot map {e.imported_from} into a python import statement"
             )
         else:
             anchor_path = os.path.dirname(self.schema_location)
             abs_import_path = os.path.join(anchor_path, e.imported_from) \
                 if not os.path.isabs(e.imported_from) else e.imported_from
             python_base_dir = os.path.dirname(
                 os.path.dirname(inspect.getfile(biolinkml)))
             python_import_dir = os.path.relpath(
                 abs_import_path, python_base_dir)
             self.v.setdefault(python_import_dir.replace('/', '.'),
                               set()).add(camelcase(e.name))
Exemplo n.º 30
0
def set_from_schema(schema: SchemaDefinition) -> None:
    for t in [schema.subsets, schema.classes, schema.slots, schema.types]:
        for k in t.keys():
            t[k].from_schema = schema.id
            if isinstance(t[k], SlotDefinition):
                fragment = underscore(t[k].name)
            else:
                fragment = camelcase(t[k].name)
            if schema.default_prefix in schema.prefixes:
                ns = schema.prefixes[schema.default_prefix].prefix_reference
            else:
                ns = str(URIRef(schema.id) + "/")
            t[k].definition_uri = f'{ns}{fragment}'