3
3
4
4
# Import Python Standard Library
5
5
import os
6
+ import sys
6
7
import time
7
8
8
9
# Import Dependencies
9
10
import ipykernel .kernelbase
11
+ import psutil
10
12
import requests
11
13
from requests .exceptions import HTTPError
12
14
@@ -43,7 +45,6 @@ def start_matlab_proxy():
43
45
headers (dict): HTTP headers required while sending HTTP requests to matlab-proxy
44
46
"""
45
47
46
- found_nb_server = False
47
48
nb_server_list = []
48
49
49
50
# The matlab-proxy server, if running, could have been started by either
@@ -59,42 +60,54 @@ def start_matlab_proxy():
59
60
except ImportError :
60
61
pass
61
62
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 ()
65
65
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
66
76
for server in nb_server_list :
67
- if server ["pid" ] == ppid :
77
+ if server ["pid" ] == jupyter_server_pid :
68
78
found_nb_server = True
69
79
nb_server = server
70
80
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
+
71
88
# Fetch JupyterHub API token for HTTP request authentication
72
89
# incase the jupyter server is started by JupyterHub.
73
90
jh_api_token = os .getenv ("JUPYTERHUB_API_TOKEN" )
74
91
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
- )
81
92
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
+ )
86
98
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
94
109
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 ()
98
111
99
112
100
113
class MATLABKernel (ipykernel .kernelbase .Kernel ):
0 commit comments