Skip to content

Commit b7e8f1c

Browse files
rashedmytPrabhakar Kumar
authored andcommitted
v0.5.2
* prepare for windows support * minor refactoring
1 parent 416b2ca commit b7e8f1c

File tree

2 files changed

+40
-26
lines changed

2 files changed

+40
-26
lines changed

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
66

77
[project]
88
name = "jupyter-matlab-proxy"
9-
version = "0.5.1"
9+
version = "0.5.2"
1010
description = "MATLAB Integration for Jupyter"
1111
readme = "README.md"
1212
license = { file = "LICENSE.md" }
@@ -41,6 +41,7 @@ dependencies = [
4141
"jupyter-server-proxy",
4242
"jupyter-contrib-nbextensions",
4343
"matlab-proxy>=0.2.9",
44+
"psutil",
4445
"requests",
4546
]
4647

src/jupyter_matlab_kernel/kernel.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
# Import Python Standard Library
55
import os
6+
import sys
67
import time
78

89
# Import Dependencies
910
import ipykernel.kernelbase
11+
import psutil
1012
import requests
1113
from requests.exceptions import HTTPError
1214

@@ -43,7 +45,6 @@ def start_matlab_proxy():
4345
headers (dict): HTTP headers required while sending HTTP requests to matlab-proxy
4446
"""
4547

46-
found_nb_server = False
4748
nb_server_list = []
4849

4950
# The matlab-proxy server, if running, could have been started by either
@@ -59,42 +60,54 @@ def start_matlab_proxy():
5960
except ImportError:
6061
pass
6162

62-
# Use parent process id of the kernel to filter Jupyter Server from the list
63-
ppid = os.getppid()
64-
nb_server = dict()
63+
# Use parent process id of the kernel to filter Jupyter Server from the list.
64+
jupyter_server_pid = os.getppid()
6565

66+
# On Windows platforms using venv/virtualenv an intermediate python process spaws the kernel.
67+
# jupyter_server ---spawns---> intermediate_process ---spawns---> jupyter_matlab_kernel
68+
# Thus we need to go one level higher to acquire the process id of the jupyter server.
69+
# Note: conda environments do not require this, and for these environments sys.prefix == sys.base_prefix
70+
is_virtual_env = sys.prefix != sys.base_prefix
71+
if sys.platform == "win32" and is_virtual_env:
72+
jupyter_server_pid = psutil.Process(jupyter_server_pid).ppid()
73+
74+
nb_server = dict()
75+
found_nb_server = False
6676
for server in nb_server_list:
67-
if server["pid"] == ppid:
77+
if server["pid"] == jupyter_server_pid:
6878
found_nb_server = True
6979
nb_server = server
7080

81+
# Error out if the server is not found!
82+
if found_nb_server == False:
83+
raise MATLABConnectionError(
84+
"""The MATLAB Kernel for Jupyter was unable to find the notebook server from which it was spawned!\n
85+
Please relaunch kernel from JupyterLab or Classic Jupyter Notebook."""
86+
)
87+
7188
# Fetch JupyterHub API token for HTTP request authentication
7289
# incase the jupyter server is started by JupyterHub.
7390
jh_api_token = os.getenv("JUPYTERHUB_API_TOKEN")
7491

75-
if found_nb_server:
76-
url = "{protocol}://localhost:{port}{base_url}matlab".format(
77-
protocol="https" if nb_server["secure"] else "http",
78-
port=nb_server["port"],
79-
base_url=nb_server["base_url"],
80-
)
8192

82-
token = nb_server["token"] if jh_api_token is None else jh_api_token
83-
headers = {
84-
"Authorization": f"token {token}",
85-
}
93+
url = "{protocol}://localhost:{port}{base_url}matlab".format(
94+
protocol="https" if nb_server["secure"] else "http",
95+
port=nb_server["port"],
96+
base_url=nb_server["base_url"],
97+
)
8698

87-
# send request to the matlab-proxy endpoint to make sure it is available.
88-
# If matlab-proxy is not started, jupyter-server starts it at this point.
89-
resp = requests.get(url, headers=headers, verify=False)
90-
if resp.status_code == requests.codes.OK:
91-
return url, nb_server["base_url"], headers
92-
else:
93-
resp.raise_for_status()
99+
token = nb_server["token"] if jh_api_token is None else jh_api_token
100+
headers = {
101+
"Authorization": f"token {token}",
102+
}
103+
104+
# send request to the matlab-proxy endpoint to make sure it is available.
105+
# If matlab-proxy is not started, jupyter-server starts it at this point.
106+
resp = requests.get(url, headers=headers, verify=False)
107+
if resp.status_code == requests.codes.OK:
108+
return url, nb_server["base_url"], headers
94109
else:
95-
raise MATLABConnectionError(
96-
"Kernel needs to be started by a Jupyter Server. Please use JupyterLab or Classic Notebook while using MATLAB Kernel for Jupyter."
97-
)
110+
resp.raise_for_status()
98111

99112

100113
class MATLABKernel(ipykernel.kernelbase.Kernel):

0 commit comments

Comments
 (0)