Skip to content

Commit 948eff5

Browse files
committed
Fixes error messages displayed when notebooks are started in non-jupyter based environments. Fixes #98
1 parent cbe2303 commit 948eff5

File tree

4 files changed

+53
-11
lines changed

4 files changed

+53
-11
lines changed

src/jupyter_matlab_kernel/base_kernel.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ def display_output(self, out):
441441
response = out["content"]
442442
self.send_response(self.iopub_socket, msg_type, response)
443443

444-
async def perform_startup_checks(self, iframe_src: str = None):
444+
async def perform_startup_checks(
445+
self, jupyter_base_url: str = None, matlab_proxy_base_url: str = None
446+
):
445447
"""
446448
One time checks triggered during the first execution request. Displays
447449
login window if matlab is not licensed using matlab-proxy.
@@ -470,19 +472,32 @@ async def perform_startup_checks(self, iframe_src: str = None):
470472
# as src for iframe to avoid hardcoding any hostname/domain information. This is done to
471473
# ensure the kernel works in Jupyter deployments. VS Code however does not work the same way
472474
# as other browser based Jupyter clients.
473-
#
474-
# TODO: Find a workaround for users to be able to use our Jupyter kernel in VS Code.
475475
if not is_matlab_licensed:
476+
if not jupyter_base_url:
477+
# happens for non-jupyter environments (like VSCode), we expect licensing to
478+
# be completed before hand
479+
self.log.debug(
480+
"MATLAB is not licensed and is in a non-jupyter environment. licensing via other means required."
481+
)
482+
raise MATLABConnectionError(
483+
"""
484+
Error: Cannot start MATLAB as no licensing information was found.
485+
Resolution: Set the environment variable MLM_LICENSE_FILE to provide a network license manager,
486+
or set MWI_USE_EXISTING_LICENSE to True if the installed MATLAB is already licensed.
487+
See https://github.com/mathworks/matlab-proxy/blob/main/Advanced-Usage.md for more information.
488+
To use Online licensing, start a MATLAB Kernel in a Jupyter notebook and login using the web interface
489+
shown upon execution of any code.
490+
"""
491+
)
476492
self.log.debug(
477493
"MATLAB is not licensed. Displaying HTML output to enable licensing."
478494
)
479-
self.log.debug(f"{iframe_src=}")
480495
self.display_output(
481496
{
482497
"type": "display_data",
483498
"content": {
484499
"data": {
485-
"text/html": f'<iframe src={iframe_src} width=700 height=600"></iframe>'
500+
"text/html": f'<iframe src={jupyter_base_url}{matlab_proxy_base_url} width=700 height=600"></iframe>'
486501
},
487502
"metadata": {},
488503
},

src/jupyter_matlab_kernel/jsp_kernel.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -201,5 +201,4 @@ async def do_shutdown(self, restart):
201201

202202
async def perform_startup_checks(self):
203203
"""Overriding base function to provide a different iframe source"""
204-
iframe_src: str = f'{self.jupyter_base_url + "matlab"}'
205-
await super().perform_startup_checks(iframe_src)
204+
await super().perform_startup_checks(self.jupyter_base_url, "matlab")

src/jupyter_matlab_kernel/mpm_kernel.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,9 @@ async def do_shutdown(self, restart):
9292

9393
async def perform_startup_checks(self):
9494
"""Overriding base function to provide a different iframe source"""
95-
iframe_src: str = (
96-
f'{self.jupyter_base_url}{self.matlab_proxy_base_url.lstrip("/")}/'
95+
await super().perform_startup_checks(
96+
self.jupyter_base_url, f'{self.matlab_proxy_base_url.lstrip("/")}/'
9797
)
98-
await super().perform_startup_checks(iframe_src)
9998

10099
# Helper functions
101100

tests/unit/jupyter_matlab_kernel/test_kernel.py

+30-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from jupyter_server import serverapp
77
from mocks.mock_jupyter_server import MockJupyterServerFixture
88

9-
from jupyter_matlab_kernel.jsp_kernel import start_matlab_proxy
9+
from jupyter_matlab_kernel.jsp_kernel import MATLABKernelUsingJSP, start_matlab_proxy
1010
from jupyter_matlab_kernel.mwi_exceptions import MATLABConnectionError
1111

1212

@@ -84,3 +84,32 @@ def test_start_matlab_proxy_jh_api_token(monkeypatch, MockJupyterServerFixture):
8484
monkeypatch.setenv("JUPYTERHUB_API_TOKEN", token)
8585
_, _, headers = start_matlab_proxy()
8686
assert headers == {"Authorization": f"token {token}"}
87+
88+
89+
async def test_matlab_not_licensed_non_jupyter(mocker):
90+
"""
91+
Test case for MATLAB not being licensed in a non-Jupyter environment.
92+
93+
This test mocks a MATLABKernelUsingJSP instance to simulate a non-Jupyter
94+
environment where MATLAB is not licensed. It checks if the appropriate
95+
exception (MATLABConnectionError) is raised when performing startup checks.
96+
"""
97+
# Mock the kernel's jupyter_base_url attribute to simulate a non-Jupyter environment
98+
kernel = mocker.MagicMock(spec=MATLABKernelUsingJSP)
99+
kernel.jupyter_base_url = None
100+
kernel.startup_error = None
101+
kernel.mwi_comm_helper = mocker.Mock()
102+
kernel.mwi_comm_helper.fetch_matlab_proxy_status = mocker.AsyncMock(
103+
return_value=(False, "down", False)
104+
)
105+
106+
# Mock the perform_startup_checks method to actually call the implementation
107+
async def mock_perform_startup_checks(*args, **kwargs):
108+
return await MATLABKernelUsingJSP.perform_startup_checks(
109+
kernel, *args, **kwargs
110+
)
111+
112+
kernel.perform_startup_checks.side_effect = mock_perform_startup_checks
113+
114+
with pytest.raises(MATLABConnectionError):
115+
await kernel.perform_startup_checks()

0 commit comments

Comments
 (0)