Repository: biolink/biolink-model-toolkit

Issue:
bmt.readthedocs.io link in README leads to 404

Discussion:

Patch:
diff --git a/README.md b/README.md
index 3dfaa6d..97d6c8b 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ python setup.py install
 
 ## Documentation
 
-The technical documentation for BMT can be found at [bmt.readthedocs.io](bmt.readthedocs.io)
+The technical documentation for BMT can be found at [https://biolink.github.io/biolink-model-toolkit/](documentation)
 
 ## Usage
 
diff --git a/bmt/toolkit.py b/bmt/toolkit.py
index 0c40b0d..7052995 100644
--- a/bmt/toolkit.py
+++ b/bmt/toolkit.py
@@ -1,5 +1,6 @@
 from functools import lru_cache, reduce
 from typing import List, Union, TextIO, Optional
+from linkml_runtime.utils.schemaview import SchemaView
 import deprecation
 from linkml_runtime.linkml_model.meta import (
     SchemaDefinition,
@@ -25,7 +26,6 @@ CACHE_SIZE = 1024
 
 logger = logging.getLogger(__name__)
 
-
 class Toolkit(object):
     """
     Provides a series of methods for performing lookups on the Biolink Model
@@ -42,6 +42,7 @@ class Toolkit(object):
     ) -> None:
         self.generator = ToolkitGenerator(schema)
         self.generator.serialize()
+        self.view = SchemaView(REMOTE_PATH)
 
     @lru_cache(CACHE_SIZE)
     def get_all_elements(self, formatted: bool = False) -> List[str]:
@@ -292,13 +293,10 @@ class Toolkit(object):
         """
         element = self.get_element(name)
         ancs = []
-        if isinstance(element, (ClassDefinition, SlotDefinition)):
-            a = self.generator.ancestors(element)
-            if mixin:
-                mixins_parents = self._get_mixin_descendants(a)
-                a = a + mixins_parents
-            ancs = a if reflexive else a[1:]
+        if isinstance(element, ClassDefinition):
+            ancs = self.view.class_ancestors(element.name, mixins=mixin, reflexive=reflexive)
         if isinstance(element, SlotDefinition):
+            ancs = self.view.slot_ancestors(element.name, mixins=mixin, reflexive=reflexive)
             filtered_ancs = self._filter_secondary(ancs)
         else:
             filtered_ancs = ancs
@@ -348,14 +346,16 @@ class Toolkit(object):
         element = self.get_element(name)
 
         if element:
-            d = self.generator.descendants(element.name, mixin)
-            if reflexive:
-                desc.append(element.name)
-            desc += d
+            if isinstance(element, ClassDefinition):
+                desc = self.view.class_descendants(element.name, mixins=mixin, reflexive=reflexive)
             if isinstance(element, SlotDefinition):
+                desc = self.view.slot_descendants(element.name, mixins=mixin, reflexive=reflexive)
                 filtered_desc = self._filter_secondary(desc)
             else:
                 filtered_desc = desc
+        else:
+            raise ValueError("not a valid biolink component")
+
         return self._format_all_elements(filtered_desc, formatted)
 
     @lru_cache(CACHE_SIZE)
@@ -913,6 +913,10 @@ class Toolkit(object):
         is_mixin = element.mixin if isinstance(element, Definition) else False
         return is_mixin
 
+    @lru_cache(CACHE_SIZE)
+    def get_inverse(self, slot_name: str):
+        return self.view.inverse(slot_name)
+
     @lru_cache(CACHE_SIZE)
     def has_inverse(self, name: str) -> bool:
         """
diff --git a/examples/bmt-tutorial.ipynb b/examples/bmt-tutorial.ipynb
index 5b2fdf4..45395f6 100644
--- a/examples/bmt-tutorial.ipynb
+++ b/examples/bmt-tutorial.ipynb
@@ -150,7 +150,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.3"
+   "version": "3.7.4"
   }
  },
  "nbformat": 4,
diff --git a/requirements.txt b/requirements.txt
index b5b9455..e160316 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
-linkml>=1.0.0
+linkml
+linkml-runtime
 deprecation>=2.0.6
 stringcase>=1.0.0
 pbr
@@ -11,3 +12,4 @@ recommonmark
 tox
 flake8
 black
+biothings-explorer


Test patch:
diff --git a/tests/unit/test_toolkit.py b/tests/unit/test_toolkit.py
index 44c885d..72ee189 100644
--- a/tests/unit/test_toolkit.py
+++ b/tests/unit/test_toolkit.py
@@ -35,6 +35,16 @@ def test_get_model_version(toolkit):
     assert version == "2.2.12"
 
 
+def test_get_inverse(toolkit):
+    assert toolkit.get_inverse('acts upstream of') == 'has upstream actor'
+
+
+def test_rna(toolkit):
+    assert 'molecular entity' in toolkit.get_descendants('biolink:Entity')
+    assert 'microRNA' in toolkit.get_descendants('biolink:Entity')
+    assert 'biolink:MicroRNA' in toolkit.get_descendants('biolink:Entity', formatted=True)
+
+
 def test_get_element_by_mapping(toolkit):
     element_name = toolkit.get_element_by_mapping("RO:0003303")
     assert element_name == "causes"
@@ -235,6 +245,8 @@ def test_descendants(toolkit):
     assert INTERACTS_WITH in toolkit.get_descendants(RELATED_TO)
     assert PHENOTYPIC_FEATURE in toolkit.get_descendants(NAMED_THING)
     assert RELATED_TO not in toolkit.get_descendants(NAMED_THING)
+    with pytest.raises(ValueError):
+        toolkit.get_descendants('biolink:invalid')
     assert "biolink:PhenotypicFeature" in toolkit.get_descendants(
         NAMED_THING, formatted=True
     )