Repository: deepchecks/deepchecks

Issue:
[FEAT] Automatically deduce output format
When running inside a jupyter kernel - output should be displayed inside the jupyter cell

When running on terminal/vscode/pycharm/other non-kernel envs - the output should be saved in the working directory of the user.

Important: Don't forget to write about this functionality in the docs, loud and clear.



Discussion:
If we will remove the auto-show does it is still needed?
the output is auto showing because of the jupyter, it doesn't break anything using not visual ide.

> the output should be saved in the working directory of the user.

It's not about whether it breaks, it's about user guidance. The user should know he has the ability to save the output as file. @ItayGabbay is leading the idea, so this issue he opened looks incompatible 
As agreed we'll have a show() function, and if the user calls the show() function inside a non-interactive python scope - a warning will be raised.

Resolving patch:
diff --git a/deepchecks/base/check.py b/deepchecks/base/check.py
--- a/deepchecks/base/check.py
+++ b/deepchecks/base/check.py
@@ -15,6 +15,7 @@
 import inspect
 import io
 import traceback
+import warnings
 from collections import OrderedDict
 from functools import wraps
 from typing import Any, Callable, List, Union, Dict, Mapping
@@ -36,7 +37,7 @@
 from deepchecks.base.dataset import Dataset
 from deepchecks.base.display_pandas import dataframe_to_html, get_conditions_table
 from deepchecks.utils.strings import get_docs_summary, split_camel_case
-from deepchecks.utils.ipython import is_ipython_display
+from deepchecks.utils.ipython import is_notebook
 from deepchecks.errors import DeepchecksValueError, DeepchecksNotSupportedError
 
 
@@ -331,11 +332,12 @@ def priority(self) -> int:
 
     def show(self, unique_id=None, show_additional_outputs=True):
         """Display check result."""
-        if is_ipython_display():
+        if is_notebook():
             self._ipython_display_(unique_id=unique_id,
                                    show_additional_outputs=show_additional_outputs)
         else:
-            print(self)
+            warnings.warn('You are running in a non-interactive python shell. in order to show result you have to use '
+                          'an IPython shell (etc Jupyter)')
 
 
 def wrap_run(func, class_instance):
diff --git a/deepchecks/base/suite.py b/deepchecks/base/suite.py
--- a/deepchecks/base/suite.py
+++ b/deepchecks/base/suite.py
@@ -12,6 +12,7 @@
 # pylint: disable=broad-except
 import abc
 import io
+import warnings
 from collections import OrderedDict
 from typing import Union, List, Optional, Tuple, Any, Container, Mapping, Callable
 
@@ -26,7 +27,7 @@
 from deepchecks.base.dataset import Dataset
 from deepchecks.base.check import CheckResult, TrainTestBaseCheck, SingleDatasetBaseCheck, ModelOnlyBaseCheck, \
                                   CheckFailure, ModelComparisonBaseCheck, ModelComparisonContext, BaseCheck
-from deepchecks.utils.ipython import is_ipython_display
+from deepchecks.utils.ipython import is_notebook
 from deepchecks.utils.typing import BasicModel
 
 
@@ -65,10 +66,11 @@ def _ipython_display_(self):
 
     def show(self):
         """Display suite result."""
-        if is_ipython_display():
+        if is_notebook():
             self._ipython_display_()
         else:
-            print(self)
+            warnings.warn('You are running in a non-interactive python shell. in order to show result you have to use '
+                          'an IPython shell (etc Jupyter)')
 
     def save_as_html(self, file=None):
         """Save output as html file.
diff --git a/deepchecks/utils/ipython.py b/deepchecks/utils/ipython.py
--- a/deepchecks/utils/ipython.py
+++ b/deepchecks/utils/ipython.py
@@ -11,14 +11,12 @@
 """Utils module containing useful global functions."""
 import re
 import subprocess
-import sys
 from functools import lru_cache
-from importlib import import_module
 
 from IPython import get_ipython  # TODO: I think we should remove ipython from mandatory dependencies
 
 
-__all__ = ['is_notebook', 'is_ipython_display', 'is_widgets_enabled']
+__all__ = ['is_notebook', 'is_widgets_enabled']
 
 
 @lru_cache(maxsize=None)
@@ -37,20 +35,6 @@ def is_notebook() -> bool:
         return False  # Probably standard Python interpreter
 
 
-@lru_cache(maxsize=None)
-def is_ipython_display() -> bool:
-    """Check whether we have IPython display module in current environment."""
-    module = 'IPython.display'
-    if module in sys.modules:
-        return True
-    try:
-        import_module(module)
-        return True
-    # pylint: disable=broad-except
-    except Exception:
-        return False
-
-
 @lru_cache(maxsize=None)
 def is_widgets_enabled() -> bool:
     """Check if we're running in jupyter and having jupyter widgets extension enabled."""


Test patch: