Repository: deepchecks/deepchecks

Issue:
[FEAT] add links to check examples to each check's one line description (Read More...)



Discussion:
1. Is there a way to have these links pointing to the relevant version? (otherwise links may be broken if we update checks / structure....)
2. links should have following utm parameters (appended to the end of the url)
?utm_source=display_output&utm_medium=referral&utm_campaign=check_link
won't links pointing to the latest be enough in most cases or even better?

Resolving patch:
diff --git a/deepchecks/__init__.py b/deepchecks/__init__.py
--- a/deepchecks/__init__.py
+++ b/deepchecks/__init__.py
@@ -11,6 +11,7 @@
 """Top module for deepchecks library."""
 import matplotlib
 import plotly.io as pio
+from pkg_resources import get_distribution, DistributionNotFound
 from .utils.ipython import is_notebook
 from .base import (
     Dataset,
@@ -60,3 +61,11 @@
 if 'notebook_connected' in pio_backends:
     pio_backends[pio_backends.index('notebook_connected')] = 'notebook'
     pio.renderers.default = '+'.join(pio_backends)
+
+
+# Set version info
+try:
+    __version__ = get_distribution('deepchecks').version
+except DistributionNotFound:
+    # If distribution can't be found, leave version empty
+    __version__ = ''
diff --git a/deepchecks/utils/strings.py b/deepchecks/utils/strings.py
--- a/deepchecks/utils/strings.py
+++ b/deepchecks/utils/strings.py
@@ -21,6 +21,7 @@
 import pandas as pd
 from pandas.core.dtypes.common import is_numeric_dtype
 
+import deepchecks
 from deepchecks.utils.typing import Hashable
 
 
@@ -64,11 +65,28 @@ def get_docs_summary(obj):
     Returns:
         (str): the object summary.
     """
+    summary = ''
     if hasattr(obj.__class__, '__doc__'):
         docs = obj.__class__.__doc__ or ''
         # Take first non-whitespace line.
         summary = next((s for s in docs.split('\n') if not re.match('^\\s*$', s)), '')
-        return summary
+
+    summary += _generate_check_docs_link_html(obj)
+    return summary
+
+
+def _generate_check_docs_link_html(check):
+    """Create from check object a link to its example page in the docs."""
+    if isinstance(check, deepchecks.BaseCheck):
+        # Get the python path of the check
+        module_path = check.__class__.__module__
+        # Transform into html path, dropping the first item which is 'deepchecks'
+        check_html_path = '/'.join(module_path.split('.')[1:])
+        # In case couldn't load version direct user to stable
+        version = deepchecks.__version__ or 'stable'
+        html_template = ('https://docs.deepchecks.com/en/{}/examples/{}.html?utm_source=display_output'
+                         '&utm_medium=referral&utm_campaign=check_link')
+        return f' <a href="{html_template.format(version, check_html_path)}" target="_blank">Read More...</a>'
     return ''
 
 


Test patch:
diff --git a/tests/utils/test_string_utils.py b/tests/utils/test_string_utils.py
--- a/tests/utils/test_string_utils.py
+++ b/tests/utils/test_string_utils.py
@@ -10,21 +10,24 @@
 #
 from datetime import datetime
 from hamcrest import assert_that, calling, raises, matches_regexp, instance_of, equal_to
-from deepchecks.utils.strings import format_datetime, get_ellipsis
+
+from deepchecks.checks import ModelInfo
+from deepchecks.utils.strings import format_datetime, get_ellipsis, _generate_check_docs_link_html
+import deepchecks
 
 
 def test_get_ellipsis():
-    result = get_ellipsis("1234", 3)
-    assert_that(result, equal_to("123..."))
-    result = get_ellipsis("1234", 4)
-    assert_that(result, equal_to("1234"))
+    result = get_ellipsis('1234', 3)
+    assert_that(result, equal_to('123...'))
+    result = get_ellipsis('1234', 4)
+    assert_that(result, equal_to('1234'))
 
 
 def test_datetime_instance_format():
     now = datetime.now()
     result = format_datetime(now)
     # %Y/%m/%d %H:%M:%S.%f %Z%z
-    pattern = rf"{now.year}/{now.month}/{now.day} {now.hour}:{now.minute}:{now.second}.{now.microsecond}"
+    pattern = rf'{now.year}/{now.month}/{now.day} {now.hour}:{now.minute}:{now.second}.{now.microsecond}'
     assert_that(
         result,
         instance_of(str),
@@ -37,7 +40,7 @@ def test_integer_timestamp_format():
     timestamp = int(now.timestamp())
     result = format_datetime(timestamp)
     # %Y/%m/%d %H:%M:%S.%f %Z%z
-    pattern = rf"{now.year}/{now.month}/{now.day} {now.hour}:{now.minute}:{now.second}.{now.microsecond}"
+    pattern = rf'{now.year}/{now.month}/{now.day} {now.hour}:{now.minute}:{now.second}.{now.microsecond}'
     assert_that(
         result,
         instance_of(str),
@@ -50,7 +53,7 @@ def test_float_timestamp_format():
     timestamp = now.timestamp()
     result = format_datetime(timestamp)
     # %Y/%m/%d %H:%M:%S.%f %Z%z
-    pattern = rf"{now.year}/{now.month}/{now.day} {now.hour}:{now.minute}:{now.second}.{now.microsecond}"
+    pattern = rf'{now.year}/{now.month}/{now.day} {now.hour}:{now.minute}:{now.second}.{now.microsecond}'
     assert_that(
         result,
         instance_of(str),
@@ -60,6 +63,25 @@ def test_float_timestamp_format():
 
 def test_format_datetime_with_unsuported_value_type():
     assert_that(
-        calling(format_datetime).with_args("hello"),
-        raises(ValueError, r"Unsupported value type - str")
+        calling(format_datetime).with_args('hello'),
+        raises(ValueError, r'Unsupported value type - str')
     )
+
+
+def test_generate_check_docs_link_html():
+    # Arrange - init some arbitrary check
+    check = ModelInfo()
+    version = deepchecks.__version__ or 'stable'
+    # Act
+    html = _generate_check_docs_link_html(check)
+    # Assert
+    assert_that(html, equal_to(f' <a href="https://docs.deepchecks.com/en/{version}/examples/checks/overview/'
+                               'model_info.html?utm_source=display_output&utm_medium=referral&utm_campaign=check_link" '
+                               'target="_blank">Read More...</a>'))
+
+
+def test_generate_check_docs_link_html_not_a_check():
+    # Act
+    html = _generate_check_docs_link_html('s')
+    # Assert
+    assert_that(html, equal_to(''))