From 24eb618c6564007dd23993fd284111ce8f7af09d Mon Sep 17 00:00:00 2001 From: Dominik Haentsch Date: Wed, 12 Jul 2023 08:48:45 +0200 Subject: [PATCH 1/2] add wait="forever" option to viewer.show --- renumics/spotlight/viewer.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/renumics/spotlight/viewer.py b/renumics/spotlight/viewer.py index dddeae8e..f35c8b10 100644 --- a/renumics/spotlight/viewer.py +++ b/renumics/spotlight/viewer.py @@ -49,6 +49,7 @@ """ import os +import threading from pathlib import Path from typing import Collection, List, Union, Optional @@ -114,7 +115,7 @@ def show( layout: Optional[_LayoutLike] = None, no_browser: bool = False, allow_filebrowsing: Union[bool, Literal["auto"]] = "auto", - wait: Union[bool, Literal["auto"]] = "auto", + wait: Union[bool, Literal["forever"], Literal["auto"]] = "auto", dtype: Optional[ColumnTypeMapping] = None, analyze: Optional[bool] = None, issues: Optional[Collection[DataIssue]] = None, @@ -130,9 +131,10 @@ def show( If "auto" (default), allow to browse if `dataset_or_folder` is a path. wait: If `True`, block code execution until all Spotlight browser tabs are closed. If `False`, continue code execution after Spotlight start. - If "auto" (default), choose the mode automatically: non-blocking for + If "forever", keep spotlight running forever, but block. + If "auto" (default), choose the mode automatically: non-blocking (`False`) for `jupyter notebook`, `ipython` and other interactive sessions; - blocking for scripts. + blocking (`True`) for scripts. dtype: Optional dict with mapping `column name -> column type` with column types allowed by Spotlight (for dataframes only). analyze: Automatically analyze common dataset issues (disabled by default). @@ -185,6 +187,9 @@ def show( else: self._server.update(config) + if not no_browser and self._server.connected_frontends == 0: + self.open_browser() + in_interactive_session = not hasattr(__main__, "__file__") if wait == "auto": # `__main__.__file__` is not set in an interactive session, do not wait then. @@ -193,13 +198,10 @@ def show( if not in_interactive_session or wait: print(f"Spotlight running on {self.url}") - if not no_browser and self._server.connected_frontends == 0: - self.open_browser() - if wait: - self.close(True) + self.close(wait) - def close(self, wait: bool = False) -> None: + def close(self, wait: Union[bool, Literal["forever"]] = False) -> None: """ Shutdown the corresponding Spotlight instance. """ @@ -212,7 +214,11 @@ def close(self, wait: bool = False) -> None: if wait: try: - self._server.wait_for_frontend_disconnect() + if wait == "forever": + threading.Event().wait() + else: + self._server.wait_for_frontend_disconnect() + except KeyboardInterrupt as e: # cleanup on KeyboarInterrupt to prevent zombie processes self.close(wait=False) @@ -332,7 +338,7 @@ def show( layout: Optional[_LayoutLike] = None, no_browser: bool = False, allow_filebrowsing: Union[bool, Literal["auto"]] = "auto", - wait: Union[bool, Literal["auto"]] = "auto", + wait: Union[bool, Literal["auto"], Literal["forever"]] = "auto", dtype: Optional[ColumnTypeMapping] = None, analyze: Optional[bool] = None, issues: Optional[Collection[DataIssue]] = None, @@ -350,10 +356,11 @@ def show( allow_filebrowsing: Whether to allow users to browse and open datasets. If "auto" (default), allow to browse if `dataset_or_folder` is a path. wait: If `True`, block code execution until all Spotlight browser tabs are closed. - If `False`, continue code execution after Spotlight start. - If "auto" (default), choose the mode automatically: non-blocking for - `jupyter notebook`, `ipython` and other interactive sessions; - blocking for scripts. + If `False`, continue code execution after Spotlight start. + If "forever", keep spotlight running forever, but block. + If "auto" (default), choose the mode automatically: non-blocking (`False`) for + `jupyter notebook`, `ipython` and other interactive sessions; + blocking (`True`) for scripts. dtype: Optional dict with mapping `column name -> column type` with column types allowed by Spotlight (for dataframes only). analyze: Automatically analyze common dataset issues (disabled by default). From 176d66ee0105486983b2b0e02e4945122eec2b76 Mon Sep 17 00:00:00 2001 From: Dominik Haentsch Date: Wed, 12 Jul 2023 11:05:35 +0200 Subject: [PATCH 2/2] nicer typing for wait=forever/auto --- renumics/spotlight/viewer.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/renumics/spotlight/viewer.py b/renumics/spotlight/viewer.py index f35c8b10..105920fc 100644 --- a/renumics/spotlight/viewer.py +++ b/renumics/spotlight/viewer.py @@ -115,7 +115,7 @@ def show( layout: Optional[_LayoutLike] = None, no_browser: bool = False, allow_filebrowsing: Union[bool, Literal["auto"]] = "auto", - wait: Union[bool, Literal["forever"], Literal["auto"]] = "auto", + wait: Union[bool, Literal["auto", "forever"]] = "auto", dtype: Optional[ColumnTypeMapping] = None, analyze: Optional[bool] = None, issues: Optional[Collection[DataIssue]] = None, @@ -218,7 +218,6 @@ def close(self, wait: Union[bool, Literal["forever"]] = False) -> None: threading.Event().wait() else: self._server.wait_for_frontend_disconnect() - except KeyboardInterrupt as e: # cleanup on KeyboarInterrupt to prevent zombie processes self.close(wait=False) @@ -338,7 +337,7 @@ def show( layout: Optional[_LayoutLike] = None, no_browser: bool = False, allow_filebrowsing: Union[bool, Literal["auto"]] = "auto", - wait: Union[bool, Literal["auto"], Literal["forever"]] = "auto", + wait: Union[bool, Literal["auto", "forever"]] = "auto", dtype: Optional[ColumnTypeMapping] = None, analyze: Optional[bool] = None, issues: Optional[Collection[DataIssue]] = None,