33
44# Import Python Standard Library
55import os
6+ import sys
67import time
78
89# Import Dependencies
910import ipykernel .kernelbase
11+ import psutil
1012import requests
1113from 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
100113class MATLABKernel (ipykernel .kernelbase .Kernel ):
0 commit comments