Exemple #1
0
    def visit_slot(self, slot_name: str, slot: SlotDefinition) -> None:
        """ Add a slot definition per slot

        @param slot_name:
        @param slot:
        @return:
        """
        sn = underscore(slot_name)
        self.emit('slot', sn)
        if slot.domain:
            self.emit('domain', sn, underscore(slot.domain))
        if slot.range:
            self.emit('range', sn, underscore(slot.range))
        for p in slot.mixins:
            self.emit('mixin', sn, underscore(p))
        if slot.is_a:
            is_a = underscore(slot.is_a)

        #uri = self.owlgen._prop_uri(slot.name)
        uri = f'http://w3id.org/biolink/vocab/{sn}'
        self.emit('has_uri', sn, uri)
        if slot.multivalued:
            self.emit('multivalued', sn)
        if slot.required:
            self.emit('required', sn)
Exemple #2
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
Exemple #3
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)
    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('   '))
Exemple #5
0
 def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str, slot: SlotDefinition) -> None:
     if self.inline:
         # If inline we have to include redefined slots
         prop = JsonObj(type=JsonObj())
         prop.type['$ref'] = self.jref(underscore(slot.name))
     elif slot.multivalued:
         prop = JsonObj(type="array", items=self.type_or_ref(slot.range))
     else:
         prop = JsonObj(type="string")
     if slot.description:
         prop.description = slot.description
     if slot.required:
         prop.required = True
     self.clsobj.properties[underscore(aliased_slot_name)] = prop
Exemple #6
0
 def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str,
                      slot: SlotDefinition) -> None:
     sn = underscore(aliased_slot_name)
     cn = underscore(cls.name)
     self.emit('class_slot', cn, sn)
     self.emit('required', sn)
     self.emit(
         'slotrange', underscore(slot.range)
     ) if slot.range in self.schema.classes or slot.range in self.schema.types else "String"
     if slot.multivalued:
         self.emit('multivalued_in', sn, cn)
     if slot.required:
         self.emit('required_in', sn, cn)
     if slot.range:
         self.emit('range_in', sn, underscore(slot.range), cn)
Exemple #7
0
 def visit_slot(self, aliased_slot_name: str, slot: SlotDefinition) -> None:
     if slot.identifier:
         slot_def = '@id'
     else:
         slot_def = {}
         if not slot.usage_slot_name:
             if slot.range in self.schema.classes:
                 slot_def['@type'] = '@id'
             elif slot.range in self.schema.enums:
                 slot_def['@context'] = ENUM_CONTEXT
                 # Add the necessary prefixes to the namespace
                 skos = self.namespaces.prefix_for(SKOS)
                 if not skos:
                     self.namespaces['skos'] = SKOS
                     skos = 'skos'
                 self.emit_prefixes.add(skos)
             else:
                 range_type = self.schema.types[slot.range]
                 if self.namespaces.uri_for(range_type.uri) == XSD.string:
                     pass
                 elif self.namespaces.uri_for(range_type.uri) in URI_RANGES:
                     slot_def['@type'] = '@id'
                 else:
                     slot_def['@type'] = range_type.uri
             slot_prefix = self.namespaces.prefix_for(slot.slot_uri)
             if not self.default_ns or not slot_prefix or slot_prefix != self.default_ns:
                 slot_def['@id'] = slot.slot_uri
                 if slot_prefix:
                     self.add_prefix(slot_prefix)
             self.add_mappings(slot)
     if slot_def:
         self.context_body[underscore(aliased_slot_name)] = slot_def
Exemple #8
0
 def _prop_uri(self, pn: SlotDefinitionName) -> URIRef:
     p = self.schema.slots.get(pn, None)
     if p is None or p.definition_uri is None:
         return self.metamodel.namespaces[METAMODEL_NAMESPACE_NAME][
             underscore(pn)]
     else:
         return URIRef(p.definition_uri)
    def visit_slot(self, aliased_slot_name: str, slot: SlotDefinition) -> None:
        with open(self.dir_path(slot), 'w') as slotfile:
            with redirect_stdout(slotfile):
                slot_curie = self.namespaces.uri_or_curie_for(self.namespaces._base, underscore(slot.name))
                slot_uri = self.namespaces.uri_for(slot_curie)
                self.element_header(slot,aliased_slot_name, slot_curie, slot_uri)
                self.mappings(slot)

                self.header(2, 'Domain and Range')
                print(f'{self.class_link(slot.domain)} ->{self.predicate_cardinality(slot)} '
                      f'{self.class_type_link(slot.range)}')

                self.header(2, 'Parents')
                if slot.is_a:
                    self.bullet(f' is_a: {self.slot_link(slot.is_a)}')

                self.header(2, 'Children')
                if slot.name in sorted(self.synopsis.isarefs):
                    for child in sorted(self.synopsis.isarefs[slot.name].slotrefs):
                        self.bullet(f' {self.slot_link(child)}')

                self.header(2, 'Used by')
                if slot.name in sorted(self.synopsis.slotrefs):
                    for rc in sorted(self.synopsis.slotrefs[slot.name].classrefs):
                        self.bullet(f'{self.class_link(rc)}')
                if aliased_slot_name == 'relation':
                    if slot.subproperty_of:
                        self.bullet(f' reifies: {self.slot_link(slot.subproperty_of) if slot.subproperty_of in self.schema.slots else slot.subproperty_of}')
                self.element_properties(slot)
    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 '')
Exemple #11
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},
Exemple #12
0
    def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str, slot: SlotDefinition) -> None:
        with open(self.dir_path(slot), 'w') as slotfile:
            with redirect_stdout(slotfile):
                self.frontmatter(f"Slot: {aliased_slot_name}")
                self.para(be(slot.description))
                slot_curi = self.namespaces.uri_or_curie_for(self.namespaces._base, underscore(slot.name))
                slot_uri = self.namespaces.uri_for(slot_curi)
                print(f'URI: [{slot_curi}]({slot_uri})')
                self.mappings(slot)

                self.header(2, 'Domain and Range')
                print(f'{self.class_link(slot.domain)} ->{self.predicate_cardinality(slot)} '
                      f'{self.class_type_link(slot.range)}')

                self.header(2, 'Inheritance')
                if slot.is_a:
                    self.bullet(f' is_a: {self.slot_link(slot.is_a)}')

                self.header(2, 'Children')
                if slot.name in sorted(self.synopsis.isarefs):
                    for child in sorted(self.synopsis.isarefs[slot.name].slotrefs):
                        self.bullet(f' {self.slot_link(child)}')

                self.header(2, 'Used by')
                if slot.name in sorted(self.synopsis.slotrefs):
                    for rc in sorted(self.synopsis.slotrefs[slot.name].classrefs):
                        self.bullet(f'{self.class_link(rc)}')
                if aliased_slot_name == 'relation':
                    if slot.subproperty_of:
                        self.bullet(f' reifies: {self.slot_link(slot.subproperty_of)}')
Exemple #13
0
    def visit_class(self, cls: ClassDefinition) -> bool:
        cn = underscore(cls.name)

        self.emit('class', cn)
        for p in cls.mixins:
            self.emit('mixin', cn, underscore(p))
        if cls.is_a:
            is_a = underscore(cls.is_a)
            self.emit('is_a', cn, is_a)
            if cls.defining_slots:
                self.emit('defining_slots', is_a,
                          [underscore(s) for s in cls.defining_slots])
        uri = f'http://w3id.org/biolink/vocab/{camelcase(cls.name)}'

        self.emit('has_uri', cn, uri)
        return True
 def visit_slot(self, aliased_slot_name: str, slot: SlotDefinition) -> None:
     if slot.identifier:
         slot_def = '@id'
     else:
         slot_def = {}
         if not slot.usage_slot_name:
             if slot.range in self.schema.classes:
                 slot_def['@type'] = '@id'
             elif slot.range in self.schema.enums:
                 # TODO: enums - fill this in
                 pass
             else:
                 range_type = self.schema.types[slot.range]
                 if self.namespaces.uri_for(range_type.uri) == XSD.string:
                     pass
                 elif self.namespaces.uri_for(range_type.uri) in URI_RANGES:
                     slot_def['@type'] = '@id'
                 else:
                     slot_def['@type'] = range_type.uri
             slot_prefix = self.namespaces.prefix_for(slot.slot_uri)
             if not self.default_ns or not slot_prefix or slot_prefix != self.default_ns:
                 slot_def['@id'] = slot.slot_uri
                 if slot_prefix:
                     self.add_prefix(slot_prefix)
             self.add_mappings(slot)
     if slot_def:
         self.context_body[underscore(aliased_slot_name)] = slot_def
 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'
Exemple #16
0
 def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str,
                      slot: SlotDefinition) -> None:
     field = GOLRField(id=underscore(aliased_slot_name),
                       description=slot.description,
                       display_name=slot.name)
     if slot.multivalued:
         field.cardinality = 'multi'
     self.class_obj.fields.append(field)
Exemple #17
0
 def end_class(self, cls: ClassDefinition) -> None:
     if self.cls_subj and self.cls_obj:
         rnode = 'relation'
         self.edge(self.aliased_slot_name(self.cls_subj), self.aliased_slot_name(self.cls_obj), label=rnode)
         self.edge(self.aliased_slot_name(self.cls_subj), rnode, style='dotted')
         self.edge(self.aliased_slot_name(self.cls_obj), rnode, style='dotted')
     if self.classdot:
         self.classdot.render(underscore(cls.name), self.dirname, view=False, cleanup=True, format=self.format)
Exemple #18
0
 def slot_name(self, name: SlotDefinitionName) -> str:
     """
     Return the underscored version of the aliased slot name if name is a slot. Prepend "unknown_" if the name
     isn't valid.
     """
     slot = self.schema.slots.get(name)
     return underscore(
         self.aliased_slot_name(slot) if slot else ("unknown " + name))
Exemple #19
0
 def slot_name(self, name: str) -> str:
     """
     Return the underscored version of the aliased slot name if name is a slot. Prepend "unknown_" if the name
     isn't valid.
     """
     slot = self.slot_for(name)
     return underscore(
         self.aliased_slot_name(slot) if slot else ("unknown " + name))
Exemple #20
0
 def visit_slot(self, slot_name: str, slot: SlotDefinition) -> None:
     # Don't emit redefined slots unless we are inlining
     if slot_name == slot.name or self.inline:
         defn = JsonObj(type="array", items=self.type_or_ref(slot.range)) if slot.multivalued \
                else self.type_or_ref(slot.range)
         if slot.description:
             defn.description = slot.description
         self.schemaobj.definitions[underscore(slot.name)] = defn
    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
Exemple #22
0
 def visit_class(self, cls: ClassDefinition) -> bool:
     # TODO: find out what to do with mappings
     if not self.closure or cls.name in self.closure:
         self.writer.writerow({'id': underscore(cls.name),
                               # 'mappings': "|".join(cls.mappings),
                               'mappings': '',
                               'description': be(cls.description)})
         return True
     return False
Exemple #23
0
 def visit_class(self, cls: ClassDefinition) -> bool:
     if not (cls.mixin or cls.abstract):
         self.class_obj = GOLRClass(id=underscore(cls.name),
                                    schema_generating=True,
                                    description=cls.description,
                                    display_name=cls.name,
                                    document_category=cls.name,
                                    weight=20)
         return True
     else:
         return False
Exemple #24
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}'
Exemple #25
0
    def visit_class_slot(self, cls: ClassDefinition, aliased_slot_name: str,
                         slot: SlotDefinition) -> None:
        with open(self.dir_path(slot), 'w') as slotfile:
            with redirect_stdout(slotfile):
                slot_curie = self.namespaces.uri_or_curie_for(
                    self.namespaces._base, underscore(slot.name))
                slot_uri = self.namespaces.uri_for(slot_curie)
                self.frontmatter(
                    **{
                        'parent': 'Slots',
                        'title': slot_curie,
                        'grand_parent': self.doc_root_title,
                        'layout': 'default'
                    })
                simple_name = slot_curie.split(':', 1)[1]
                self.header(
                    1, f"Type: {simple_name}" +
                    (f" _(deprecated)_" if slot.deprecated else ""))
                for s in slot.in_subset:
                    self.badges(s, f'{s}-subset-label')

                self.para(be(slot.description))
                print(f'URI: [{slot_curie}]({slot_uri})')

                self.header(2, 'Domain and Range')
                print(
                    f'{self.class_link(slot.domain)} ->{self.predicate_cardinality(slot)} '
                    f'{self.class_type_link(slot.range)}')

                self.header(2, 'Parents')
                if slot.is_a:
                    self.bullet(f' is_a: {self.slot_link(slot.is_a)}')

                self.header(2, 'Children')
                if slot.name in sorted(self.synopsis.isarefs):
                    for child in sorted(
                            self.synopsis.isarefs[slot.name].slotrefs):
                        self.bullet(f' {self.slot_link(child)}')

                self.header(2, 'Used by')
                if slot.name in sorted(self.synopsis.slotrefs):
                    for rc in sorted(
                            self.synopsis.slotrefs[slot.name].classrefs):
                        self.bullet(f'{self.class_link(rc)}')
                if aliased_slot_name == 'relation':
                    if slot.subproperty_of:
                        self.bullet(
                            f' reifies: {self.slot_link(slot.subproperty_of)}')
                self.element_properties(slot)
Exemple #26
0
    def class_box(self, cn: ClassDefinitionName) -> str:
        """ Generate a box for the class.  Populate its interior only if (a) it hasn't previously been generated and
        (b) it appears in the gen_classes list

        @param cn:
        @return:
        """
        slot_defs: List[str] = []
        if cn not in self.box_generated and (not self.focus_classes
                                             or cn in self.focus_classes):
            cls = self.schema.classes[cn]
            for slot in self.filtered_cls_slots(
                    cn,
                    all_slots=True,
                    filtr=lambda s: s.range not in self.schema.classes):
                if True or cn in slot.domain_of:
                    mod = self.prop_modifier(cls, slot)
                    slot_defs.append(
                        underscore(self.aliased_slot_name(slot)) + mod + ':' +
                        underscore(slot.range) + self.cardinality(slot))
            self.box_generated.add(cn)
        self.referenced.add(cn)
        return '[' + camelcase(cn) + ('|' + ';'.join(slot_defs)
                                      if slot_defs else '') + ']'
Exemple #27
0
 def end_class(self, cls: ClassDefinition) -> None:
     fn = os.path.join(self.dirname, underscore(cls.name + '-config.yaml'))
     with open(fn, 'w') as f:
         f.write(as_yaml(self.class_obj))
Exemple #28
0
 def _type_uri(self, tn: TypeDefinitionName) -> URIRef:
     return self.namespaces[METAMODEL_LOCAL_NAME][underscore(tn)]
Exemple #29
0
 def _prop_uri(self, pn: SlotDefinitionName) -> URIRef:
     return self.namespaces[METAMODEL_LOCAL_NAME][underscore(pn)]
Exemple #30
0
 def slot_name_for(slot: SlotDefinition) -> str:
     return underscore(slot.alias if slot.alias else slot.name)