Skip to content

Commit

Permalink
⚡️ Warn instead of raising the exception when ipylab is not installed (
Browse files Browse the repository at this point in the history
…#283)

* try all path methods without ipylab import error

* server_exception at the end

* upd installation instructions

* do not log or display consecutive cells for version 1

* check interactive envs

* err text
  • Loading branch information
Koncopd authored May 8, 2024
1 parent 3f635d1 commit 9d8df62
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 23 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ Install: ![pyversions](https://img.shields.io/pypi/pyversions/nbproject)
pip install nbproject
```

Also consider installing `ipylab` for interactive features
if you use `nbpoject` on `jupyter lab`

```
pip install ipylab
```

Get started:

```
Expand Down
9 changes: 9 additions & 0 deletions nbproject/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
"""
__version__ = "0.10.2"

from .dev._jupyter_lab_commands import _init_frontend

# init jupyter lab frontend immediately on import
# nothing happens if this is not jupyter lab
try:
_init_frontend()
except: # noqa: E722
pass

from . import dev
from ._header import header
from ._meta import meta
Expand Down
11 changes: 8 additions & 3 deletions nbproject/_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .dev._frontend_commands import _reload_notebook, _save_notebook
from .dev._initialize import initialize_metadata
from .dev._jupyter_communicate import notebook_path
from .dev._jupyter_lab_commands import _ipylab_is_installed
from .dev._metadata_display import display_html, table_metadata
from .dev._notebook import Notebook, read_notebook, write_notebook

Expand All @@ -17,7 +18,7 @@
msg_init_complete = (
"Init complete. Hit save & reload from disk, i.e, *discard* editor content. If you"
" do not want to lose editor changes, hit save *before* running `header()`."
" Consider using Jupyter Lab for a seamless interactive experience."
" Consider using Jupyter Lab with ipylab installed for a seamless interactive experience."
)

msg_inconsistent_parent = (
Expand Down Expand Up @@ -113,9 +114,13 @@ def header(
global _time_run, _filepath, _env
_time_run, _filepath, _env = time_run, filepath, env

interactive_envs = ["notebook"]
if _ipylab_is_installed():
interactive_envs.append("lab")

# initialize
if "nbproject" not in nb.metadata:
if env in ("lab", "notebook"):
if env in interactive_envs:
_save_notebook(env)
nb = read_notebook(filepath) # type: ignore

Expand All @@ -129,7 +134,7 @@ def header(
_output_table(nb, table_metadata(metadata, nb, time_run))
write_notebook(nb, filepath) # type: ignore

if env in ("lab", "notebook"):
if env in interactive_envs:
_reload_notebook(env)
else:
raise SystemExit(msg_init_complete)
Expand Down
7 changes: 4 additions & 3 deletions nbproject/_publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .dev._check_last_cell import check_last_cell
from .dev._consecutiveness import check_consecutiveness
from .dev._frontend_commands import _save_notebook
from .dev._jupyter_lab_commands import _ipylab_is_installed
from .dev._notebook import read_notebook
from .dev._set_version import set_version

Expand All @@ -13,7 +14,7 @@ def run_checks_for_publish(
*, calling_statement: str, i_confirm_i_saved: bool = False, **kwargs
):
"""Runs all checks for publishing."""
if meta.env in ("lab", "notebook"):
if meta.env == "notebook" or (meta.env == "lab" and _ipylab_is_installed()):
_save_notebook(meta.env)
else:
pretend_no_test_env = (
Expand All @@ -26,8 +27,8 @@ def run_checks_for_publish(
elif not i_confirm_i_saved:
raise RuntimeError(
"Make sure you save the notebook in your editor before publishing!\n"
"You can avoid the need for manually saving in Jupyter Lab or Notebook,"
" which auto-save the buffer during publish."
"You can avoid the need for manually saving in Jupyter Lab with ipylab installed"
" or Notebook, which auto-save the buffer during publish."
)

notebook_title = meta.live.title
Expand Down
13 changes: 9 additions & 4 deletions nbproject/dev/_jupyter_communicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from nbproject._logger import logger

from ._jupyter_lab_commands import _lab_notebook_path
from ._jupyter_lab_commands import _ipylab_is_installed, _lab_notebook_path

DIR_KEYS = ("notebook_dir", "root_dir")

Expand Down Expand Up @@ -153,14 +153,19 @@ def notebook_path(return_env=False):
nb_path = PurePath(os.environ["JPY_SESSION_NAME"])
return (nb_path, "lab" if env is None else env) if return_env else nb_path

if server_exception is not None:
raise server_exception

# no running servers
if servers_nbapp == [] and servers_juserv == []:
logger.warning("Can not find any servers running.")

logger.warning(
"Can not find the notebook in any server session or by using other methods."
)
if not _ipylab_is_installed():
logger.warning(
"Consider installing ipylab (pip install ipylab) if you use jupyter lab."
)

if server_exception is not None:
raise server_exception

return None
29 changes: 19 additions & 10 deletions nbproject/dev/_jupyter_lab_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,30 @@
app = None


# called in __init__.py
def _init_frontend():
from ipylab import JupyterFrontEnd
try:
from ipylab import JupyterFrontEnd

global app
if app is None and is_run_from_ipython:
app = JupyterFrontEnd()
global app
if app is None and is_run_from_ipython:
app = JupyterFrontEnd()
except ImportError:
pass


def _save_notebook():
_init_frontend()

if app is not None:
app.commands.execute("docmanager:save")
sleep(1)


def _reload_notebook():
_init_frontend()

if app is not None:
app.commands.execute("docmanager:reload")


def _lab_notebook_path():
_init_frontend()

if app is None:
return None

Expand All @@ -43,3 +41,14 @@ def _lab_notebook_path():
nb_path = None

return nb_path


def _ipylab_is_installed():
if app is not None:
return True
try:
import ipylab

return True
except ImportError:
return False
7 changes: 5 additions & 2 deletions nbproject/dev/_metadata_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from pydantic import BaseModel

from nbproject._logger import logger

from ._consecutiveness import check_consecutiveness
from ._lamin_communicate import lamin_user_settings
from ._notebook import Notebook
Expand Down Expand Up @@ -147,8 +149,9 @@ def table_metadata(
if dm.parent() is not None:
table.append(["parent", dm.parent()])

if version != "0":
consecutiveness = check_consecutiveness(notebook)
if version not in {"0", "1"}:
with logger.mute():
consecutiveness = check_consecutiveness(notebook)
table.append(["consecutive_cells", str(consecutiveness)])

dep_store = dm.pypackage()
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dependencies = [
"orjson",
"importlib-metadata",
"stdlib_list; python_version < '3.10'",
"lamin_utils>=0.5.0",
"lamin_utils>=0.13.2",
]

[project.urls]
Expand Down

0 comments on commit 9d8df62

Please sign in to comment.